且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何安全地保存用户名/密码(本地)?

更新时间:2023-02-02 20:39:43

如果你只是要验证/验证输入的用户名和密码,使用Rfc2898DerivedBytes类(也称为密码基于密钥推导函数2或PBKDF2)。这比,因为没有从RFC2898DerivedBytes的结果返回给密码去没有实际的方式使用加密像三重DES或AES更安全。您只能从一个密码,结果去了。见Is它确定,派生从密码字符串加密密钥和IV时使用的密码的SHA1哈希作为盐?的用于.NET或String加密/密码为C#Metro风格获得的WinRT /地铁解密。

If you are just going to verify/validate the entered user name and password, use the Rfc2898DerivedBytes class (also known as Password Based Key Derivation Function 2 or PBKDF2). This is more secure than using encryption like Triple DES or AES because there is no practical way to go from the result of RFC2898DerivedBytes back to the password. You can only go from a password to the result. See Is it ok to use SHA1 hash of password as a salt when deriving encryption key and IV from password string? for an example and discussion for .Net or String encrypt / decrypt with password c# Metro Style for WinRT/Metro.

如果你是存储重复使用的密码,比如其提供给第三方使用的Windows数据保护API(DPAPI)。这使用操作系统生成和保护键和三重DES 的加密算法来加密和解密信息。这意味着你的应用程序不必担心使用加密时,生成和保护加密密钥,主要关心的问题。

If you are storing the password for reuse, such as supplying it to a third party, use the Windows Data Protection API (DPAPI). This uses operating system generated and protected keys and the Triple DES encryption algorithm to encrypt and decrypt information. This means your application does not have to worry about generating and protecting the encryption keys, a major concern when using cryptography.

在C#中,使用System.Security.Cryptography.ProtectedData类。例如,要加密的数据块,用ProtectedData.Protect()$c$c>:

In C#, use the System.Security.Cryptography.ProtectedData class. For example, to encrypt a piece of data, use ProtectedData.Protect():

// Data to protect. Convert a string to a byte[] using Encoding.UTF8.GetBytes().
byte[] plaintext; 

// Generate additional entropy (will be used as the Initialization vector)
byte[] entropy = new byte[20];
using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
    rng.GetBytes(entropy);
}

byte[] ciphertext = ProtectedData.Protect(plaintext, entropy,
    DataProtectionScope.CurrentUser);

存放熵和密文牢固,如在与这样只有当前用户可以阅读它设置权限的文件或注册表项。为了访问原始数据,使用ProtectedData.Unprotect()$c$c>:

byte[] plaintext= ProtectedData.Unprotect(ciphertext, entropy,
    DataProtectionScope.CurrentUser);

请注意,有额外的安全注意事项。例如,避免将密码等作为字符串秘密。字符串是不可改变的,是他们不能在内存中通知,以便有人在看应用程序的内存或者内存转储可能会看到密码。使用 SecureString的或一个byte [],而不是记住处置或零它们作为一旦密码不再需要。

Note that there are additional security considerations. For example, avoid storing secrets like passwords as a string. Strings are immutable, being they cannot be notified in memory so someone looking at the application's memory or a memory dump may see the password. Use SecureString or a byte[] instead and remember to dispose or zero them as soon as the password is no longer needed.