我一直在使用 C# 为自己编写一个小程序,我可以用它来存储我的密码,然后检索它们以进行查看/编辑。
虽然密码以加密格式存储到磁盘中,但当它们被读入内存以在表单上显示/编辑时,它们是未加密的。
我了解到,在内存中有未加密的密码是一个相当大的安全问题,所以我遇到了这SecureString
门课。
有没有比使用SecureString
类更安全的方法,还是SecureString
名副其实?
我一直在使用 C# 为自己编写一个小程序,我可以用它来存储我的密码,然后检索它们以进行查看/编辑。
虽然密码以加密格式存储到磁盘中,但当它们被读入内存以在表单上显示/编辑时,它们是未加密的。
我了解到,在内存中有未加密的密码是一个相当大的安全问题,所以我遇到了这SecureString
门课。
有没有比使用SecureString
类更安全的方法,还是SecureString
名副其实?
SecureString
将其文本加密保存在内存中,您可以在不需要时立即将其丢弃。问题是,当您想以几乎任何其他方式显示或使用它时,您必须将其转换为普通字符串,这是不安全的。
此外,我不会过分依赖它——系统无需任何解密密钥即可对其进行解密,这意味着坚定的黑客很可能也能做到这一点。当黑客控制您的计算机时,您无法确定任何事情,他可能能够访问任何未使用具有良好密钥的良好算法加密的任何内容。
SecureString 以某种方式保护字符串的内存实例,但是您应该注意一些重大缺点。
SecureStringToBSTR(input);
SecureString 需要以逐个字符的方式填充,因为没有 .Text 属性 Get 或 Set 访问器可供使用。在包括 MSDN 在内的博客上,您经常会看到如下代码:
public static SecureString StringToSecureString(string input)
{
SecureString output = new SecureString();
int l = input.Length;
char[] s = input.ToCharArray(0, l);
foreach (char c in s)
{
output.AppendChar(c);
}
return output;
}
这段代码的一个重要问题是,开发人员一开始就允许input
字符串存在于内存中。用于从用户那里收集此密码的 PasswordBox 的用户控件或 WinForm TextBox 永远不应在一次操作中收集整个密码,因为
而是考虑使用 KeyPress 从用户那里检索每个字符的选项,否则,我相信 WPF 的 PasswordBox 默认由 SecureString 支持(其他人可能会确认这一点)。
最后,还有更简单的方法可以从 Key Loggers 等用户那里收集密码。我的建议是考虑你的用户人口统计、暴露风险,并确定像 SecureString 这样微不足道的东西是否真的会削减它。
SecureString 正是它的名字所说的,你猜到了:它保存了也在内存中加密的字符串,所以是的,这是正确的方法。
见这里:
表示应保密的文本。文本在使用时被加密以保护隐私,并在不再需要时从计算机内存中删除。这个类不能被继承。
你们让这种方式太复杂了。没有人问这是否是解决问题的最佳方法。他们只是想看看一些工作代码。天哪。在本例中,passwordPre 是使用您的专有解密算法从资源(例如配置文件)中解密的字符串。
string passwordPre = DecryptProprietary(objectReferringToPassword);
char[] passwordChars = passwordPre.ToCharArray();
System.Security.SecureString securePassword = new System.Security.SecureString(); // in production, this should probably be a global variable
foreach (char c in passwordChars)
securePassword.AppendChar(c);
string decryptedPassword = new System.Net.NetworkCredential(string.Empty, securePassword).Password; // this is how to convert it to a string for quick usage to access the protected resource
因此,您可以快速使用解密的密码来访问您需要的任何资源,然后通过退出该方法来处理它。