.NET中如何安全地存储认证信息(C#)
2017-01-01 11:52
1031 查看
.NET中如何安全地存储认证信息(C#)
TODO: 本文由 赤石俊哉 翻译整理,您可以将本文自由地用于学习交流。如需用于其他用途请征得作者的同意。原文链接:How to securely save username/password (local)? - StackOverFlow
验证输入的用户名和密码
如果你只希望验证输入的用户名和密码是否匹配,可以使用Rfc2898DerivedBytes类(即
PBKDF2)。这比起使用诸如三次DES以及AES这样的加密算法来说要更安全一些,因为从
RFC2898DerivedBytes产生的结果逆推出密码原文是不可行的。你只能将密码转换成
PBKDF2的结果。
你可以参考使用密码的SHA1哈希值作为密码字符串推导加密秘钥和向量的盐,是否可行?,
这里面有一个示例,也讨论了在WinRT/Metro环境的.Net环境下C# Metro风格的密码字符串加密解密。
存储密码
如果你希望存储密码以便以后进行复用,你可以使用Windows Data Protection API(DPAPI)。
它是使用了操作系统生成并且保护的密钥进行三次DES加密算法来加密解密信息的。
这就意味着你的应用程序可以省去一个大麻烦,那就是它不需要去关心密钥如何去生成以及保护。
在
C#中,使用
System.Security.Cryptography.ProtectedData类。
举个例子,使用
ProtectedData.Protect()加密一小段数据:
// 需要被保护的数据。使用Encoding.UTF8.GetBytes()将一个字符串转换成byte数组。 byte[] plaintext; // 生成一个附加的熵(用于向量的初始化) byte[] entropy = new byte[20]; using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()){ rng.GetBytes(entropy); } byte[] ciphertext = ProtectedData.Protect(plaintext, entropy, DataProtectionScope.CurrentUser);
安全地存储熵值(
entropy)和加密后文本(
ciphertext),比如存储在一个只有当前用户具有读写权限的文件或者注册表项内。
在程序中,需要访问原始数据的时候,只需要使用
ProtectedData.Unprotect():
byte[] plaintext = ProtectedData.Unprotect(ciphertext, entropy, DataProtectionScope.CurrentUser);
还有一些其他要注意的安全考虑,比如,避免直接将像密码这类的隐私信息存储为一个字符串(
string),这样做的话在内存中是不可被通知的,所以其他人要是查看程序的内存或者Dump内存的时候,就会看到密码。
使用
SecureString或者一个byte数组来代替。在不需要使用密码的时候,尽快释放掉他们,或者是全部填写0。
相关文章推荐
- 【.NET】C#中各类获取设备存储信息的各类方法
- 如何得到硬盘序列号?.NET版本[C#]
- 如何使用.NET生成C#源代码
- [愚翁专栏]如何用C#获得文件信息以及扩展信息
- ADO.NET 2.0:如何排除错误信息「当目前没有数据时,尝试读取无效」(C#)
- Java vs C# —— 且看微软的.Net和Sun公司的J2EE如何对垒
- 在.net中如何把调用存储过程代码写入数据连接层中
- 如何使用 ADO.NET 和 Visual C# .NET 调用带参数的存储过程
- 如何用C#获得文件信息以及扩展信息
- 请问C#如何修改与显示文件的摘要信息
- IBatis.Net如何获取存储过程的Output的参数值
- C#中如何获取注册表信息
- C#中如何获取注册表信息
- 如何得到硬盘序列号?.NET版本[C#]
- 如何在.NET(based on c#)中调用系统功能
- MSN 如何在客户端安全的记录会话信息
- .net C#线程连接Join的技巧,如何真正让一个线程结束,另外一个线程启动
- c# 正确读取存储中文,以及如何获取字节流编码
- c# 如何将图片信息从数据库中读取出来放入pictureBox1中:
- 如何在.net平台合理安全的使用Named Shared Memory以在进程间共享数据