【问题标题】:in C#, what is the proper way to handle sensitive data such as a password?在 C# 中,处理密码等敏感数据的正确方法是什么?
【发布时间】:2012-06-15 15:11:05
【问题描述】:

这个应用程序显示一个带有文本框的表单,用户应该在其中输入用于解密文档的密码。

我的代码如下所示:

string password = passwordTextBox.Text;
...
DecryptDocument(password);

但有人告诉我,从技术上讲,这是一个安全漏洞,因为即使在应用程序关闭后,代表密码的数据也可能保留在内存中。

我尝试使用 System.Security.SecureString 类,但现在我正在处理指向 CoTaskMem 的指针,这似乎使问题变得更糟:

SecureString password = new SecureString();
foreach(char i in passwordTextBox.Text.ToCharArray())
password.AppendChar(i);

IntPtr ptr = Marshal.SecureStringToCoTaskMemAnsi(password);
int length = password.Length;
byte[] bytes = new byte[length];

Marshal.Copy(ptr, bytes, 0, length);

DecryptDocument(Encoding.Default.GetString(bytes));

Marshal.FreeCoTaskMem(ptr);

如您所见,我似乎并没有让应用程序更安全,因为迟早我必须接受输入 (passwordTextBox.Text) 并将其转换为我可以传递给DecryptDocument() 函数。

有没有办法解决这个问题,还是我应该只处理这个安全漏洞?

【问题讨论】:

  • “但有人告诉我,从技术上讲,这是一个安全漏洞,因为即使在应用程序关闭后,代表密码的数据也可能保留在内存中。”- 虽然这是真的,它会在内存中的随机位置。你什么都不担心。“有没有办法解决这个问题,还是我应该只处理这个安全漏洞?”那会是什么漏洞?
  • @Ramhound,如果您不担心将文本放在内存中的随机位置,那么根本不值得使用 SecureString。公平地说,它实际上只增加了少量的安全性;主要问题是崩溃转储,尽管它们已经泄漏了各种敏感信息(即当前为工作目的而解密的所有内容)。 SecureString 真正为您带来的唯一好处是降低了泄露密码的可能性,这可能会危及密钥(或相关用户访问的其他服务,如果他们重复使用他们的密码)。

标签: c# security passwords securestring


【解决方案1】:

如果您真的想使用 SecureString,则需要端到端使用它,最好一次只与一个字符交互。每当将字符串解密为字符数组时,您都需要在使用完毕后明确清除内存。这样做的后果:

  1. 您应该使用直接与 SecureString 一起操作的安全 TextBox 控件。一个很好的例子请参见here

  2. 您应该修改 DecryptDocument 以直接获取 SecureString。

  3. 您需要实现解密,以尽可能少地处理解密字符。 .NET 中的一些加密架构实际上直接支持 SecureString。如果做不到这一点,最好的办法是使用非托管缓冲区,并在完成后将其明确清除。

【讨论】:

    猜你喜欢
    • 2012-04-15
    • 1970-01-01
    • 2023-01-12
    • 2011-12-12
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 2011-03-09
    • 2011-11-29
    相关资源
    最近更新 更多