Jon*_*Jon 2 .net c# encryption hash salt
我有下面的代码来散列/存储/检索密码数据,但我的第一个单元测试失败了。
我相信它的编码导致了问题,因为当调用 GetBytes 时它会返回byte[38],byte[36]我认为它应该是 20 。
当我将其存储在数据库中时,我必须将其转换为字符串。
有任何想法吗?谢谢
[Fact]
public void EncryptDecryptPasswordShouldMatch()
{
string password = "password";
string passwordKey = string.Empty;
string passwordSalt = string.Empty;
Helpers.CreatePasswordHash(password, out passwordSalt, out passwordKey);
Assert.True(Helpers.PasswordsMatch(passwordSalt, passwordKey, password));
}
public static bool PasswordsMatch(string passwordSalt, string passwordKey, string password)
{
byte[] salt = Encoding.UTF8.GetBytes(passwordSalt);
byte[] key = Encoding.UTF8.GetBytes(passwordKey);
using (var deriveBytes = new Rfc2898DeriveBytes(password, salt))
{
byte[] newKey = deriveBytes.GetBytes(20); // derive a 20-byte key
if (!newKey.SequenceEqual(key))
return false;
}
return true;
}
public static void CreatePasswordHash(string password, out string passwordSalt, out string passwordKey)
{
// specify that we want to randomly generate a 20-byte salt
using (var deriveBytes = new Rfc2898DeriveBytes(password, 20))
{
byte[] salt = deriveBytes.Salt;
byte[] key = deriveBytes.GetBytes(20); // derive a 20-byte key
passwordSalt = Encoding.UTF8.GetString(salt);
passwordKey = Encoding.UTF8.GetString(key);
}
}
Run Code Online (Sandbox Code Playgroud)
使用Base64将二进制值编码为字符串,它可以处理任意字节序列。UTF-8 用于在 unicode 文本和字节之间进行转换,并非每个有效的字节序列都对 UTF-8 有效。使用 Utf-8 将密码(文本)转换为字节,但使用 Base64 进行盐和哈希。
Convert.ToBase64String并且Convert.FromBase64String应该可以解决问题。
一些附加说明:
key,叫它hash。我会在函数中连接哈希和盐CreatePasswordHash,这样调用者就不必费心拥有两个单独的值。
类似于return Base64Encode(salt)+"$"+Base64Encode(hash)thenstring.Split在验证功能中使用的东西。
建议使用恒定时间比较来验证,但似乎您的定时侧通道实际上不太可能被利用。