关于通过从中创建 System.String 来取消 SecureString 的所有保留 除了 ,怎么做?

如何将普通的 System.Security.SecureString 转换为 System.String?

我相信很多熟悉 SecureString 的人都会回答说永远不要将 SecureString 转换为普通的 .NET 字符串,因为它会删除所有安全保护。 我知道 。但是现在我的程序无论如何都用普通字符串做所有事情,我正在努力提高它的安全性,虽然我将使用一个向我返回 SecureString 的 API,但我并没有试图使用它来提高我的安全性。

我知道 Marshal.SecureStringToBSTR,但我不知道如何使用该 BSTR 并从中制作 System.String。

对于那些可能需要知道我为什么要这样做的人,好吧,我从用户那里获取密码并将其作为 html 表单 POST 提交,以将用户登录到网站。所以......这真的必须用托管的、未加密的缓冲区来完成。如果我什至可以访问非托管、未加密的缓冲区,我想我可以在网络流上逐字节地写入流,并希望这样可以保证密码的安全。我希望至少对其中一种情况有答案。

最佳答案

使用 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) 访问原始数据:
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);
  }
}

关于c# - 如何将 SecureString 转换为 System.String?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/818704/

10-16 10:00