在.NET中,我们有SecureString类,这很好,但是当你尝试使用它时会遇到问题,因为(例如)要对字符串进行哈希处理,你需要明文。我在这里编写了一个函数,可以给定一个接受字节数组并输出字节数组的哈希函数,对SecureString进行哈希处理。
private static byte[] HashSecureString(SecureString ss, Func<byte[], byte[]> hash)
{
// Convert the SecureString to a BSTR
IntPtr bstr = Marshal.SecureStringToBSTR(ss);
// BSTR contains the length of the string in bytes in an
// Int32 stored in the 4 bytes prior to the BSTR pointer
int length = Marshal.ReadInt32(bstr, -4);
// Allocate a byte array to copy the string into
byte[] bytes = new byte[length];
// Copy the BSTR to the byte array
Marshal.Copy(bstr, bytes, 0, length);
// Immediately destroy the BSTR as we don't need it any more
Marshal.ZeroFreeBSTR(bstr);
// Hash the byte array
byte[] hashed = hash(bytes);
// Destroy the plaintext copy in the byte array
for (int i = 0; i < length; i++) { bytes[i] = 0; }
// Return the hash
return hashed;
}
我相信这个函数可以正确地哈希字符串,并且在函数返回时,假设提供的哈希函数行为良好并且不会复制任何输入而不是自己擦除它,它也可以正确地清除任何明文副本。我有没有漏掉什么重要的内容?
SecureString
并不是为了使对正在运行的进程的攻击变得不可能,而是为了防止内存转储(没有系统内存的转储)。即使对于正在运行的进程,攻击者也需要在受攻击的进程下拥有执行权限才能检索未加密的字符串-而不仅仅是读取权限。 - M.Stramm