Является ли SecureString классом только для записи? - PullRequest
1 голос
/ 14 мая 2011

Я недавно обнаружил SecureString, и он, кажется, подходит для идеального приложения, где я хочу в основном инициализировать статическую секретную строку в начале приложения, а затем сделать ее доступной только для чтения и использовать ее на протяжении всего жизненного цикла приложения (какчасть хэша).

У меня проблемы с пониманием того, как даже использовать класс SecureString. Из того, что я могу сказать, вы можете установить SecureString, но нет способа сравнить значение или получить значение в любомпуть.

Какова цель этого класса, если он предназначен только для записи?

Ответы [ 2 ]

3 голосов
/ 14 мая 2011

Нет, это не только для записи: вы можете извлечь обычный .NET String из SecureString, используя класс Marshal :

IntPtr ptr = Marshal.SecureStringToBSTR(secureString);
string str = Marshal.PtrToStringBSTR(ptr);
Marshal.ZeroFreeBSTR(ptr);
return str;

Обратите внимание, что этовыделяет неуправляемую память, поэтому вам необходимо обязательно ее освободить (с Marshal.ZeroFreeBSTR), чтобы избежать утечек.И само собой разумеется, что после того, как вы конвертируете его в строку .NET, вы теряете преимущества SecureString (строка останется в памяти до тех пор, пока не будет скопирована на GC, она может быть перенесена на диск и т. Д.).

Цель класса SecureString заключается в том, что вы можете использовать его в API, где должна быть защищена конфиденциальность пользовательских данных (например, паролей или номеров кредитных карт) (например, если ваше приложение дает сбой и мини-дамп сохраняется вдиск).Несколько классов в .NET Framework (например, PasswordBox.SecurePassword ) принимают объект SecureString, чтобы избежать раскрытия этих данных.

0 голосов
/ 14 мая 2011

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

        #region SecureString Manipulation
    /// <summary>
    /// Convert a Securestring to a regular string (not considered best practice, but make sure it's not in memory if you can help it)
    /// </summary>
    /// <param name="securePassword">Password stored in a secure string</param>
    /// <returns>regular string of securestring password</returns>
    public static string ConvertToUnsecureString(this System.Security.SecureString securePassword)
    {
        if (securePassword == null)
            throw new ArgumentNullException("securePassword");

        IntPtr unmanagedString = IntPtr.Zero;
        try
        {
            unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(securePassword);
            return Marshal.PtrToStringUni(unmanagedString);
        }
        finally
        {
            Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
        }
    }

    /// <summary>
    /// Pass a text password to this function to return a SecureString (doesn't store the password in memory)
    /// </summary>
    /// <param name="password">Text version of a password</param>
    /// <returns>SecureString of a password (not readable by memory)</returns>
    public static SecureString ConvertToSecureString(this string password)
    {
        if (password == null)
            throw new ArgumentNullException("password");

        var secure = new SecureString();
        foreach (var c in password.ToCharArray())
            secure.AppendChar(c);
        return secure;
    }
    #endregion
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...