是否可以将SecureString用作ProtectedData.Protect的参数?

时间:2018-11-01 12:33:26

标签: c# .net securestring

是否可以在不首先将其转换为常规SecureString的情况下提供ProtectData.Protect作为string方法的参数吗?

当前,我具有以下代码来执行此操作。我已经使用SecureString来保存密码输入的密码/成为字符串的唯一点是在下面的方法调用中。这有望减少不安全字符串的寿命,但是有什么办法可以进一步改善它呢?

此逻辑在我的邮件应用程序中不可用,而在助手应用程序中可用,其唯一要点是接受输入并返回加密的输出/寿命为数分钟,其中大部分将用尽等待用户输入(因此内存中没有密码)。

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);
        }
    }
}

是否可以选择直接将SecureString用作参数,而不必首先将其转换为string

如果失败,这是否是可以调用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 个答案:

没有答案