代码之家  ›  专栏  ›  技术社区  ›  JohnLBevan

是否可以将SecureString用作ProtectedData的参数。保护

  •  1
  • JohnLBevan  · 技术社区  · 6 年前

    有没有办法提供一个 SecureString 作为对 ProtectData.Protect 方法,而不首先将其转换为正则表达式 string ?

    目前我有下面的代码来执行这个操作。我用过 安全字符串 要从输入中保存密码/密码成为字符串的唯一点是在下面的方法调用中。这有望减少不安全字符串的寿命,但有没有办法进一步改善这一点?

    这种逻辑在我的邮件应用程序中不可用,而是在助手应用程序中可用。助手应用程序的唯一目的是获取输入并返回加密输出,其使用寿命为分钟,其中大部分时间将用于等待用户输入(因此内存中没有密码)。

    public string EncryptString(SecureString secureUnencryptedString)
    {
        if (secureUnencryptedString == null) return null;
        return EncryptString(secureUnencryptedString.ToInsecureString());
    }
    
    private string EncryptString(string insecureUnencryptedString)
    {
        Debug.Assert(insecureUnencryptedString != null);
        byte[] encryptedData = ProtectedData.Protect
        (
            Encoding.Unicode.GetBytes(insecureUnencryptedString),
            entropy,
            scope
        );
        return Convert.ToBase64String(encryptedData);
    }
    
    //...
    //made internal so anyone using my library won't think this should be used elsewhere
    internal static class SecureStringExtension
    {
        internal static string ToInsecureString(this SecureString value)
        {
            if (value == null) return null;
            IntPtr valuePtr = IntPtr.Zero;
            try
            {
                valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
                return Marshal.PtrToStringUni(valuePtr);
            }
            finally
            {
                Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
            }
        }
    }
    

    有没有选择使用 安全字符串 直接作为参数,而不是首先必须将其转换为 一串 ?

    如果做不到这一点,这会是少数有理由打电话的情况之一吗 System.GC.Collect() (即在 finally 街上的街区 EncryptString 方法)以提高从内存中删除此不安全字符串的可能性?例如

    public string EncryptString(SecureString secureUnencryptedString)
    {
        if (secureUnencryptedString == null) return null;
        try
        {
            return EncryptString(secureUnencryptedString.ToInsecureString());
        }
        finally
        {
            GC.Collect(); //doesn't guarantee cleanup, but improves the chances / helps minimise the potential lifetime of the insecure string
        }
    }
    
    0 回复  |  直到 6 年前