Подтвердить что ты не робот

Как SecureString "зашифрован" и все еще используется?

В соответствии с MSDN SecureString содержимое зашифровывается для дополнительной безопасности, так что если программа поменяется на диск, содержимое строки не может быть обнюхано.

Как такое шифрование возможно мне интересно? Алгоритм был бы исправлен и, следовательно, либо хорошо известен, либо вычитается (скажем, один из семи широко используемых в отраслевых алгоритмах), и в программе должен быть ключ. Таким образом, злоумышленник может получить зашифрованную строку, извлечь ключ и дешифровать данные.

Как такое шифрование может быть полезным?

4b9b3361

Ответ 1

Я цитирую статью о DPAPI, которая используется для вывода ключа. Это должно ответить на большинство вопросов, которые у вас есть о SecureString.

И да, SecureString имеет недостатки и не полностью безопасен, есть способы доступа к данным, например, ввод Hawkeye в процесс упоминается в MSDN как способ извлечь SecureString. Я лично не подтвердил эту информацию.

Управление ключами DAPI

DAPI - это метод шифрования на основе симметричных оснований, что означает, что он использует один и тот же ключ для шифрования и дешифрования данных. Прежде чем перейти к некоторым примерам использования DAPI, стоит упомянуть, как DAPI управляет своим ключом. По большей части процесс управления ключами DAPI является невидимым, и вам, как правило, не нужно беспокоиться об этом, что является основной причиной того, что DAPI является хорошим подходом.

Во введении я написал, что главный ключ генерируется из пароля пользователя. Это не полная картина. На самом деле Windows использует пароль входа пользователя для генерации главного ключа. Этот главный ключ защищен паролем пользователя, а затем сохраняется вместе с профилем пользователя. Затем этот главный ключ используется для получения нескольких других ключей, а также других ключей, которые используются для защиты данных.

Причина, по которой Windows делает это, позволяет приложениям добавлять дополнительную информацию, называемую энтропией, к процессу генерации отдельных ключей. Вы видите, что каждое приложение, работающее под учетной записью входа в систему, использует один и тот же ключ, тогда каждое приложение может отменить защиту данных, защищенных DAPI. Иногда вы можете захотеть, чтобы приложения могли совместно использовать данные, защищенные DAPI; однако иногда вы этого не сделаете. Позволяя приложению вносить энтропию в генерацию ключа, тогда этот ключ становится специфичным для приложения, и любые данные, которые защищены этим приложением, могут быть снова незащищены, если они знают энтропию.

Хотя генерация главного ключа, а затем использование этого главного ключа для генерации других ключей для выполнения фактического шифрования может показаться длинным наклонным подходом, у него есть одно важное преимущество. Поскольку существует дополнительный уровень абстракции между основным ключом, защищенным паролем пользователя, и фактическими ключами, используемыми для защиты данных, это означает, что когда пользователь меняет свой пароль, тогда только мастер-ключ должен быть повторно защищен; ни одна из защищенных данных не нуждается в повторной защите. Поскольку главный ключ намного меньше по размеру, чем данные, тогда достигается значительная экономия производительности.

При изменении пароля пользователя, конечно, создается новый главный ключ. Этот новый мастер-ключ затем используется для создания новых отдельных ключей. Однако, поскольку все ранее созданные отдельные ключи были получены из старого главного ключа, тогда Windows должна хранить все предыдущие мастер-ключи, что и делает. Windows никогда не забывает мастер-ключ, и все защищенные данные отмечены идентификатором GUID, который указывает, какой мастер-ключ использовался для защиты данных. Таким образом, с точки зрения приспособляемости DAPI может справиться с изменениями паролей пользователей, одновременно обеспечивая: a) что защищенные данные не нуждаются в повторной защите, и b) что ключи, используемые для предварительной защиты данных, по-прежнему доступны, и c ) он делает все это автоматически для вас.

Если компьютер не является членом домена, DAPI может использовать только незащищенные данные на том же компьютере, который использовался для его защиты.

Также, как и защита уровня пользователя, в том, что главные ключи основаны на пользовательских паролях, а защищенные данные для одного пользователя не могут быть защищены другим пользователем, DAPI также обеспечивает защиту уровня компьютера, поскольку главные ключи основаны на конкретных машинах Информация. Мастер-ключи уровня машины позволяют приложениям хранить защищенные данные, чтобы они могли быть незащищенными всеми пользователями приложения. Единственное различие в уже описанном процессе - главный ключ генерируется из информации, специфичной для машины, а не для конкретной информации пользователя.

Ответ 2

Я посмотрел на один пункт кода, и он использует Windows advapi32 для выполнения своей грязной работы. Таким образом, ключ не сохраняется в памяти приложения.

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static int SystemFunction040([In, Out] SafeBSTRHandle pDataIn, [In] uint cbDataIn, [In] uint dwFlag)

Что лучше известно как RtlEncryptMemory.

Он расшифровывается с помощью RtlDecryptMemory (SystemFunction041).

Я уверен, что компилятор что-то делает с SecurityCriticalAttribute.

изменить это было отражено с помощью 4.0. другие версии могут отличаться.

Ответ 3

Как уже сообщали другие, содержимое SecureString зашифровывается с использованием DPAPI, поэтому ключи не хранятся в вашем приложении, они являются частью ОС. Я не на 100% положителен, но я бы предположил, что SecureString использует пользовательский ключ, так что, даже если другой процесс получит доступ к блоку памяти, он должен работать под одними и теми же учетными данными, чтобы просто расшифруйте содержимое с помощью DPAPI. Даже если это не так, машинный ключ (теоретически) предотвращает дешифровку строки, если ее переносят в другую систему.

Более важным с SecureString является то, как и когда вы его используете. Он должен использоваться для хранения строковых данных, которые необходимо сохранить в памяти для "расширенных" периодов времени, но которые часто не нужны в их расшифрованной форме. В какой-то момент вам придется расшифровать его в обычный старый System.String или System.Char[]. Это когда он наиболее уязвим в памяти. Если вы делаете это слишком часто, у вас есть несколько копий расшифрованной строки, плавающей в памяти, ожидающей сбора.

Как правило, если я читаю зашифрованные данные (например, учетные данные для входа), которые мне нужно сохранить для нечастого использования (например, для взаимодействия с PayPal или Amazon API), я сохраняю/кеширую эти учетные данные как SecureString, затем расшифровать его по мере необходимости достаточно долго, чтобы совершать вызовы веб-службы, и гарантировать, что срок службы любой расшифрованной копии будет всего лишь несколькими строками кода.

Вероятно, также целесообразно использовать критические блоки или похожие на подсказку CLR, что он не должен переключиться на контекст, пока используется расшифрованная строка, чтобы повысить вероятность того, что все расшифрованные копии будут собраны до того, как память будет кэширована или заменена.

Ответ 4

По волшебству DPAPI:

Этот класс хранит свои данные с использованием модели защищенной памяти Data Protection API (DPAPI). Другими словами, данные всегда находятся в зашифрованном виде, в то время как они хранятся внутри SecureString. Ключ шифрования управляется локальной подсистемой безопасности (LSASS.EXE), а через DPAPI данные могут быть дешифрованы посредством межпроцессного обмена.