所有关于通过在其中创建 System.String 来解除 SecureString 安全的 保留 ,怎么做?
如何将普通的 System.Security.SecureString 转换为 System.String?
我敢肯定,熟悉 SecureString 的许多人都会回应说,永远不应该将 SecureString 转换为普通的 .NET 字符串,因为它会删除所有安全保护。 我知道 。但是现在我的程序无论如何都用普通字符串做所有事情,我正在努力增强它的安全性,虽然我将使用一个向我返回 SecureString 的 API,但我 并不 想用它来提高我的安全性。
我知道 Marshal.SecureStringToBSTR,但我不知道如何获取该 BSTR 并从中制作 System.String。
对于那些可能想知道我为什么要这样做的人,好吧,我从用户那里获取密码并将其作为 html 表单 POST 提交以将用户登录到网站。所以......这确实必须使用托管的未加密缓冲区来完成。如果我什至可以访问未管理的、未加密的缓冲区,我想我可以在网络流上逐字节地进行流写入,并希望整个过程都能保证密码的安全。我希望至少能找到其中一种情况的答案。
使用System.Runtime.InteropServices.Marshal类:
System.Runtime.InteropServices.Marshal
String SecureStringToString(SecureString value) { IntPtr valuePtr = IntPtr.Zero; try { valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value); return Marshal.PtrToStringUni(valuePtr); } finally { Marshal.ZeroFreeGlobalAllocUnicode(valuePtr); } }
如果要避免创建托管字符串对象,可以使用以下方法访问原始数据Marshal.ReadInt16(IntPtr, Int32):
Marshal.ReadInt16(IntPtr, Int32)
void HandleSecureString(SecureString value) { IntPtr valuePtr = IntPtr.Zero; try { valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value); for (int i=0; i < value.Length; i++) { short unicodeChar = Marshal.ReadInt16(valuePtr, i*2); // handle unicodeChar } } finally { Marshal.ZeroFreeGlobalAllocUnicode(valuePtr); } }