在C#中,处理敏感数据(如密码)的正确方法是什么?

时间:2012-06-15 15:11:05

标签: c# security passwords securestring

此应用程序显示带有文本框的表单,用户应输入用于解密文档的密码。

我的代码如下:

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()函数。

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

1 个答案:

答案 0 :(得分:8)

如果你真的想使用SecureString,它需要端到端使用,最好一次只能与一个角色进行交互。每当字符串被解密为字符数组时,您将需要在使用它时明确清除内存。后果:

  1. 您应该使用直接使用SecureString操作的安全TextBox控件。有关一个好例子,请参阅here

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

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

相关问题