Интересности      Книги      Утилиты    

8 августа 2011 г.

Безопасные строки в .net–класс SecureString

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

Примеров, где безопасность строк может быть посталвена под сомнение можно найти сколько угодно. В данном случае речь идет о безопасном хранении строки в памяти, чтобы ее невозможно было узнать сняв дамп.

Для таких целей в .net существует специальный класс – System.Security.SecureString. Строка созданая посредством этого класса остается зашифрованой в памяти, поэтому узнать ее сняв дамп или просканировав память – не получится, разве что придется узнав ключ симмертического шифрований.  Также основной особенностью таких строк есть то, как они располагаются в памяти. SecureString – “закреплен” в памяти, чтобы избежать содание копий объекта сборщиком мусора .NET, сохраняя всего одну копию. Также такие строки не попадуть в swap файл.


SecureString создается по особенному – по-символьно. То есть код создания экзепляра такого объекта будет выглядеть так:

SecureString secureStr = new SecureString();
for (int i = 0; i < someString.Length; i++)
    secureStr.AppendChar(someString[i]);

secureStr.MakeReadOnly();

Метод MakeReadOnly делает объект read-only и запрещает его редактирование в дальнейшем.

Вычитка SecureString также усложнена:
IntPtr stringPointer = Marshal.SecureStringToBSTR(secureStringObj);
try
{
    string normalString = Marshal
.PtrToStringBSTR(stringPointer);
}
finally
{
    Marshal.ZeroFreeBSTR(stringPointer);
}

К тому же он реализует IDisposable для того чтобы в нужный момент можно было вручную удалить его из памяти и удалять такую строку сразу после использования – рекомендовано.

using (SecureString ss = new SecureString())
{
    // use the secure string
}

SecureString наследуется от абстрактного CriticalFinalizerObject. Это обеспечивает что код финализации SecureString маркируется как критический и выполняется всегда даже если поток был завершен abnormally. И как результат SecureString успешно очищается из памяти.

SecureString не защищает от всех бед, а он защищает строку которая хранится в памяти и обеспечивает возможность ее быстрого удаления. SecureString создается посимвольно что позволяет использовать его в связки с ”password” textbox’ами. Существуют готовые реализции таких textbox’ов, хотя их еще нужно проверять, и написать свой, если понадобится, много труда не составит.

Некоторые части .NET Framework используют SecureString, вот некоторые примеры:

  • В WPF элемент управления PasswordBox хранит строки внутри как SecureString
  • Свойство Password класса System.Diagnostics.ProcessInfo – SecureString
  • Конструктор класса X509Certificate2 принимает SecureString как пароль

Смысл SecureString проявляется тогда когда он создается и наполняется правильно. Дело в том что если мы будем создавать его из уже существующей строки  в памяти, или конвертировать из существующей строки, то обычная строка останется какое-то время в памяти, что, фактически, сведет на нет все наши усилия и пляски с SecureString. Поэтому основные применения это посимольный ввод в “password” текст боксах или посимольное чтение из потока. Возможно также вычитывать какие-то зашифрованые данные и расшифровывать их сразу в SecureString .

Комментариев нет:

Отправить комментарий