1

我最近发现了 SecureString,它似乎适合一个完美的应用程序,我想在应用程序开始时基本上初始化一个静态秘密字符串,然后将其设为只读并在应用程序的整个生命周期中使用它(作为一个哈希)。

我无法理解如何使用 SecureString 类。据我所知,您可以设置 SecureString,但无法比较值或以任何方式检索值。

如果这个类是只写的,它的目的是什么?

4

2 回答 2

3

不,它不是只写的:您可以使用MarshalString从.NET 中检索常规 .NET :SecureString

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

请注意,这会分配非托管内存,因此您需要确保释放它(使用Marshal.ZeroFreeBSTR)以避免泄漏。不言而喻,一旦将其转换为 .NET 字符串,您将失去 SecureString 的好处(字符串将保留在内存中,直到它被 GC'ed,它可能被分页到磁盘等)。

SecureString 类的目的是您可以在应保护用户数据(例如,密码或信用卡号)隐私的 API 中使用它(例如,如果您的应用程序崩溃并且小型转储被保存到磁盘)。.NET Framework 中的少数类(例如PasswordBox.SecurePassword)采用 SecureString 对象以避免暴露此数据。

于 2011-05-14T05:11:45.663 回答
0

这里有两种方式,一种将其转换为安全字符串和从安全字符串转换的方法。当然,将它存储在安全字符串中的全部目的是首先防止它出现在内存中。

        #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
于 2011-05-14T05:27:16.563 回答