我之前从未加密过密码,这是我在this article的帮助下实现的。这篇文章没有包括盐,所以我必须自己解决这个问题:
UTF8Encoding encoder = new UTF8Encoding();
byte[] salt = new byte[8];
new Random().NextBytes(salt);
byte[] encodedPassword = encoder.GetBytes(txtPassword.Text);
byte[] saltedPassword = new byte[8 + encodedPassword.Length];
System.Buffer.BlockCopy(salt, 0, saltedPassword, 0, 8);
System.Buffer.BlockCopy(encodedPassword, 0, saltedPassword, 8, encodedPassword.Length);
byte[] encryptedPassword = new MD5CryptoServiceProvider().ComputeHash(saltedPassword);
byte[] saltedEncryptedPassword = new byte[8 + encryptedPassword.Length];
System.Buffer.BlockCopy(salt, 0, saltedEncryptedPassword, 0, 8);
System.Buffer.BlockCopy(encryptedPassword, 0, saltedEncryptedPassword, 8, encryptedPassword.Length);
将saltedEncryptedPassword
存储在数据库中。正如您可能注意到的那样,在将涉及盐的字节数组连接在一起时遇到了一些麻烦。我做得对吗,还是有更好的方法?感谢。
答案 0 :(得分:6)
答案 1 :(得分:0)
我只将salt值和哈希值(不是saltedencryptedPassword)存储在数据库的不同列中,并使用输入的密码重新生成哈希值。你在这里找到了类似的答案Hash and salt passwords in C#。1`
我有时只将GUID作为salt值,并在散列之前将其添加到密码中。
MD5不再安全(2004年被中国人黑了),你可以用SHA256或SHA512代替。编辑:然而,这些算法计算速度非常快,因此更容易破解。 @SLaks建议使用scrypt或PBKDF2,因为它们更难计算。 在Rfc2898DeriveBytes下的.NET中有一个内置的PBKDF2实现。
另一点:我不会每次都创建一个新的Random()对象。如果你在短时间内调用它,每次都会生成相同的随机数序列,因为种子值是基于时间的。
答案 2 :(得分:-1)
不,这不好。 MD5不再好了。它与自身相撞而不被信任。你应该使用SHA256。
public string getSHA256(string input)
{
try
{
return BitConverter.ToString(SHA256Managed.Create().ComputeHash(Encoding.Default.GetBytes(input))).Replace(“-”, “”).ToLower();
}
catch (Exception e)
{
return string.Empty;
}
}
答案 3 :(得分:-1)
我总是将SHA2-512用于我的密码的哈希。在我看来,密码永远不应该加密,但总是哈希(无法追溯到原始密码)。
但请不要再使用MD5,现在可以轻松将其翻译回密码。