Класс System.Security.SecureString

Важно!

Рекомендуется не использовать SecureString класс для новой разработки в .NET (Core) или при переносе существующего кода в .NET (Core). Дополнительные сведения см. в разделе SecureString не следует использовать.

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

SecureString — это строковый тип, предоставляющий меру безопасности. Он пытается избежать хранения потенциально конфиденциальных строк в памяти процесса в виде обычного текста. (Однако сведения об ограничениях см. в разделеНасколько безопасна Защита SecureString? section.) Значение экземпляра SecureString автоматически защищается с помощью механизма, поддерживаемого базовой платформой при инициализации экземпляра или при изменении значения. Приложение может отобразить неизменяемый экземпляр и предотвратить дальнейшее MakeReadOnly изменение путем вызова метода.

Максимальная длина экземпляра SecureString составляет 65 536 символов.

Важно!

Этот тип реализует интерфейс IDisposable. Завершив использование экземпляра типа, его следует удалить напрямую или косвенно. Чтобы сделать это прямо, вызовите его метод Dispose в блоке try/catch. Чтобы сделать это косвенно, используйте языковые конструкции, такие как using (в C#) или Using (в Visual Basic). Дополнительные сведения см. в разделе "Использование объекта, реализующего IDisposable" в статье об интерфейсе IDisposable.

Класс SecureString и его члены не видны COM. Дополнительные сведения см. в разделе ComVisibleAttribute.

Строка и SecureString

Экземпляр System.String класса является неизменяемым и, если он больше не нужен, невозможно программно запланировать сборку мусора. То есть экземпляр доступен только для чтения после его создания, и невозможно предсказать, когда экземпляр будет удален из памяти компьютера. Так как System.String экземпляры неизменяемы, операции, которые, как представляется, изменяют существующий экземпляр, фактически создают копию для управления. Следовательно, если String объект содержит конфиденциальную информацию, например пароль, номер кредитной карта или персональные данные, может возникнуть риск, что информация может быть обнаружена после его использования, так как приложение не может удалить данные из памяти компьютера.

Объект SecureString похож на String объект, имеющий текстовое значение. Однако значение SecureString объекта закреплено в памяти, может использовать механизм защиты, например шифрование, предоставленное базовой операционной системой, может быть изменен до тех пор, пока приложение не помечает его как доступное только для чтения, и его можно удалить из памяти компьютера, вызывая Dispose метод или сборщик мусора .NET.

Обсуждение ограничений SecureString класса см. в разделе "Защита SecureString?" .

Операции SecureString

Класс SecureString включает элементы, которые позволяют выполнять следующие действия:

Создайте SecureString экземпляр SecureString объекта, вызвав его конструктор без параметров.

Добавление символов в SecureString объект Можно добавить один символ за раз в SecureString объект, вызвав его AppendChar или InsertAt метод.

Важно!

SecureString Объект никогда не должен создаваться из Stringобъекта, так как конфиденциальные данные уже подвержены последствиям сохраняемости памяти неизменяемого String класса. Лучший способ создания SecureString объекта — из неуправляемого источника символа во время, например Console.ReadKey метода.

Удаление символов из SecureString объекта Можно заменить отдельный символ путем вызова метода, удаления отдельного символа RemoveAtSetAt путем вызова метода или удаления всех символов из SecureString экземпляра путем вызова Clear метода.

SecureString Сделайте объект доступным только для чтения после определения строки, представляющей SecureString объект, вызовите его MakeReadOnly метод, чтобы сделать строку доступной только для чтения.

Получение сведений об объекте Класс SecureString содержит только два члена, которые предоставляют сведения о SecureString строке: его Length свойство, указывающее количество единиц кода в кодировке UTF16 в строке, а также IsReadOnlyметод , указывающий, является ли экземпляр только для чтения.

Отпустите память, выделенную SecureString экземпляру, так как SecureString реализует IDisposable интерфейс, вы освобождаете память, вызывая Dispose метод.

Класс SecureString не имеет элементов, которые проверяют, сравнивают или преобразуют значение SecureStringобъекта. Отсутствие таких элементов помогает защитить значение экземпляра от случайного или вредоносного воздействия. Используйте соответствующие члены System.Runtime.InteropServices.Marshal класса, например SecureStringToBSTR метод, для управления значением SecureString объекта.

Библиотека классов .NET обычно использует SecureString экземпляры следующим образом:

SecureString и взаимодействие

Так как операционная система не поддерживает SecureStringнапрямую, необходимо преобразовать значение SecureString объекта в обязательный тип строки перед передачей строки в собственный метод. Класс Marshal имеет пять методов, которые выполняют следующие действия:

Каждый из этих методов создает строку с четким текстом в неуправляемой памяти. Это ответственность разработчика до нуля и освобождения этой памяти, как только она больше не нужна. Каждый из методов преобразования строк и выделения памяти имеет соответствующий метод для отсчитывания и освобождения выделенной памяти:

Метод выделения и преобразования Нулевой и бесплатный метод
Marshal.SecureStringToBSTR Marshal.ZeroFreeBSTR
Marshal.SecureStringToCoTaskMemAnsi Marshal.ZeroFreeCoTaskMemAnsi
Marshal.SecureStringToCoTaskMemUnicode Marshal.ZeroFreeCoTaskMemUnicode
Marshal.SecureStringToGlobalAllocAnsi Marshal.ZeroFreeGlobalAllocAnsi
Marshal.SecureStringToGlobalAllocUnicode Marshal.ZeroFreeGlobalAllocUnicode

Насколько безопасна Защита SecureString?

При правильном SecureString создании экземпляр обеспечивает большую защиту данных, чем a String. При создании строки из источника символов во время создает несколько промежуточных в памяти, String а создает SecureString только один экземпляр. Сборка мусора String объектов недетерминирована. Кроме того, поскольку память не закреплена, сборщик мусора создаст дополнительные копии значений String при перемещении и сжатия памяти. В отличие от этого, память, выделенная SecureString для объекта, закреплена, и эта память может быть освобождена путем вызова Dispose метода.

Несмотря на то, что данные, хранящиеся в экземпляре, являются более безопасными, чем данные, хранящиеся в SecureStringString экземпляре, имеют значительные ограничения на то, насколько безопасный SecureString экземпляр. Например:

Платформа

В операционной системе Windows содержимое внутреннего массива символов экземпляра SecureString шифруется. Тем не менее, из-за отсутствия API или проблем управления ключами шифрование недоступно на всех платформах. Из-за этой зависимости SecureString платформы не шифрует внутреннее хранилище на платформе, отличной от Windows. Другие методы используются на этих платформах для обеспечения дополнительной защиты.

Длительность

Даже если SecureString реализация может воспользоваться преимуществами шифрования, обычный текст, назначенный SecureString экземпляру, может быть предоставлен в разное время:

  • Так как Windows не предлагает безопасную реализацию строки на уровне операционной системы, .NET по-прежнему должен преобразовать безопасное строковое значение в его представление обычного текста, чтобы использовать его.

  • Всякий раз, когда значение безопасной строки изменяется такими методами, как AppendChar или RemoveAt, его необходимо расшифровать (то есть преобразовать обратно в обычный текст), изменить и затем зашифровать снова.

  • Если в вызове взаимодействия используется безопасная строка, она должна быть преобразована в строку ANSI, строку Юникода или двоичную строку (BSTR). Дополнительные сведения см. в разделе SecureString и взаимодействия .

Интервал времени, для которого SecureString предоставляется значение экземпляра, просто сокращен по сравнению с классом String .

служба хранилища и использование, как правило, SecureString класс определяет механизм хранения строковых значений, которые должны быть защищены или сохранены в конфиденциальности. Однако за пределами .NET механизм использования не поддерживается SecureString. Это означает, что безопасная строка должна быть преобразована в доступную для использования форму (обычно чистую текстовую форму), которую можно распознать в целевом объекте, и это расшифровка и преобразование должны происходить в пользовательском пространстве.

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