初学者散列和加盐
Beginner hashing & salting
所以我对编程 (C#) 相当陌生,尤其是一般的密码学。我尝试通过使用 MD5 散列算法复制几个函数并学习它的工作原理来学习一些。然后我连接到数据库并进行了登录和重置密码功能。然而,当我尝试制作相同的密码时,问题出现了,我意识到无论我在哈希值中添加随机生成的盐,哈希值都会变成相同的。
string MD5(string input)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] bytes = md5.ComputeHash(Encoding.Unicode.GetBytes(input));
string result = BitConverter.ToString(bytes).Replace("-", String.Empty);
return result.ToLower();
}
public static byte[] GenerateSalt()
{
RNGCryptoServiceProvider saltGenerator = new RNGCryptoServiceProvider();
byte[] salt = new byte[24];
saltGenerator.GetBytes(salt);
return salt;
}
所以这是我生成盐和散列输入字符串的函数。这是通过在 WinForms 中填写两个文本框来重置密码的代码。
private void HashNewPassword(out byte[] salt, out string hashedPassword)
{
string tempHash;
salt = null;
hashedPassword = null;
if (txtPassword1.Text == txtPassword2.Text)
{
tempHash = txtPassword1.Text;
salt = GenerateSalt();
hashedPassword = MD5(MD5(tempHash + salt));
}
else
{
throw new Exception();
}
}
最后,click-even 函数:
private void btnFinished_Click(object sender, EventArgs e)
{
try
{
string hashedPassword;
byte[] salt;
HashNewPassword(out salt, out hashedPassword);
AddPasswordToDB(salt, hashedPassword);
}
catch (Exception error)
{
MessageBox.Show(error.Message + " : " + error.GetType().ToString());
}
}
正如您在下面看到的,散列值相同,但盐不同。我加盐的方式不应该吗?
bec78d2acfd2eb4f5d7da2fd231bad1c 0x21B5F48096E31092FCCD20EE22EF9B3C307ADDC1C31B8D84
bec78d2acfd2eb4f5d7da2fd231bad1c 0xC063774EBBD4FAED268811C84D70662F4DDB53BCA52A6720
对此有合理的解释,还是代码有问题?
另外,我不熟悉散列算法,只是偶然发现并想了解更多信息。有更简单的方法吗?我读过其他看起来很容易使用的算法,但正如我所说,我对此并不熟悉。哈希算法之间的安全差异无关紧要。我确实读过 MD5 很旧而且 不那么安全,但它对我的使用来说绰绰有余。
提前致谢。
在不涉及安全方面的情况下,我相信您得到的是相同的哈希值,因为您没有将 salt 连接为字符串:tempHash + salt
salt
是一个字节数组,通过将 +
与 string
一起使用,它的 ToString()
方法在连接之前被调用。这将不会产生具有实际值的字符串。
尝试将数组转换为实际字符串:
System.Text.Encoding.Default.GetString(salt)
一个小例子来进一步阐明行为:
byte[] salt = new byte[] {67,79,79,76};
Console.WriteLine(salt.ToString()); // prints System.Byte[]
string saltAsString = System.Text.Encoding.Default.GetString(salt);
Console.WriteLine(saltAsString); // prints COOL
所以我对编程 (C#) 相当陌生,尤其是一般的密码学。我尝试通过使用 MD5 散列算法复制几个函数并学习它的工作原理来学习一些。然后我连接到数据库并进行了登录和重置密码功能。然而,当我尝试制作相同的密码时,问题出现了,我意识到无论我在哈希值中添加随机生成的盐,哈希值都会变成相同的。
string MD5(string input)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] bytes = md5.ComputeHash(Encoding.Unicode.GetBytes(input));
string result = BitConverter.ToString(bytes).Replace("-", String.Empty);
return result.ToLower();
}
public static byte[] GenerateSalt()
{
RNGCryptoServiceProvider saltGenerator = new RNGCryptoServiceProvider();
byte[] salt = new byte[24];
saltGenerator.GetBytes(salt);
return salt;
}
所以这是我生成盐和散列输入字符串的函数。这是通过在 WinForms 中填写两个文本框来重置密码的代码。
private void HashNewPassword(out byte[] salt, out string hashedPassword)
{
string tempHash;
salt = null;
hashedPassword = null;
if (txtPassword1.Text == txtPassword2.Text)
{
tempHash = txtPassword1.Text;
salt = GenerateSalt();
hashedPassword = MD5(MD5(tempHash + salt));
}
else
{
throw new Exception();
}
}
最后,click-even 函数:
private void btnFinished_Click(object sender, EventArgs e)
{
try
{
string hashedPassword;
byte[] salt;
HashNewPassword(out salt, out hashedPassword);
AddPasswordToDB(salt, hashedPassword);
}
catch (Exception error)
{
MessageBox.Show(error.Message + " : " + error.GetType().ToString());
}
}
正如您在下面看到的,散列值相同,但盐不同。我加盐的方式不应该吗?
bec78d2acfd2eb4f5d7da2fd231bad1c 0x21B5F48096E31092FCCD20EE22EF9B3C307ADDC1C31B8D84
bec78d2acfd2eb4f5d7da2fd231bad1c 0xC063774EBBD4FAED268811C84D70662F4DDB53BCA52A6720
对此有合理的解释,还是代码有问题? 另外,我不熟悉散列算法,只是偶然发现并想了解更多信息。有更简单的方法吗?我读过其他看起来很容易使用的算法,但正如我所说,我对此并不熟悉。哈希算法之间的安全差异无关紧要。我确实读过 MD5 很旧而且 不那么安全,但它对我的使用来说绰绰有余。
提前致谢。
在不涉及安全方面的情况下,我相信您得到的是相同的哈希值,因为您没有将 salt 连接为字符串:tempHash + salt
salt
是一个字节数组,通过将 +
与 string
一起使用,它的 ToString()
方法在连接之前被调用。这将不会产生具有实际值的字符串。
尝试将数组转换为实际字符串:
System.Text.Encoding.Default.GetString(salt)
一个小例子来进一步阐明行为:
byte[] salt = new byte[] {67,79,79,76};
Console.WriteLine(salt.ToString()); // prints System.Byte[]
string saltAsString = System.Text.Encoding.Default.GetString(salt);
Console.WriteLine(saltAsString); // prints COOL