一尘不染

如何将SecureString转换为System.String?

c#

有关取消保护通过创建它以System.String你的SecureString的所有预订 一边 ,怎么能做到呢?

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

我敢肯定,许多熟悉SecureString的人都会做出回应,那就是永远不要将SecureString转换为普通的.NET字符串,因为它会删除所有安全保护措施。
我知道
。但是现在,我的程序无论如何都使用普通字符串完成所有操作,并且我试图提高其安全性,尽管我将使用向我返回SecureString的API,但我并 没有
尝试使用它来提高安全性。

我知道Marshal.SecureStringToBSTR,但我不知道如何获取该BSTR并从中创建System.String。

对于那些可能想知道我为什么要这样做的人,我从用户处获取密码,并将其以html表单POST的形式提交,以将用户登录到网站。所以…这实际上必须使用托管的,未加密的缓冲区来完成。如果我什至可以访问非托管,未加密的缓冲区,我想我可以在网络流上逐字节写入流,并希望这样可以使密码始终保持安全。我希望至少能对这些情况中的一种作出回答。


阅读 801

收藏
2020-05-19

共1个答案

一尘不染

使用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);
  }
}
2020-05-19