我用的是.net port of libsodium。哈希生成函数有两种形式,一种接受字节数组,另一种接受字符串:
public static byte[] ArgonHashBinary(string password, string salt, long opsLimit, int memLimit, long outputLength = ARGON_SALTBYTES)
public static byte[] ArgonHashBinary(byte[] password, byte[] salt, long opsLimit, int memLimit, long outputLength = ARGON_SALTBYTES)
我遇到的问题是当输入值相同时,两个表单都会产生相同的散列。
var saltAsBytes = PasswordHash.ArgonGenerateSalt();
var saltAsString = Encoding.UTF8.GetString(saltAsBytes);
var tmp = Encoding.UTF8.GetBytes(saltAsString);
var hash1 = PasswordHash.ArgonHashBinary(password, saltAsString, 6, 134217728, 16);
var hash2 = PasswordHash.ArgonHashBinary( Encoding.UTF8.GetBytes(password), saltAsBytes, 6, 134217728, 16);
任何带有“passwordhash”的东西都是lib钠而不是我的代码。
当我把它从一个字符串转换成一个字节数组的时候。字节数组数组的长度总是不同的。
ArgonGenerateSalt()
生成长度为16的字节数组。当我把它从一般30度以上的弦转换回来时(每次都不同,因为产生的盐不同)。为什么我要转换为utf8?因为这就是他们在内部所做的:
https://github.com/adamcaudill/libsodium-net/blob/master/libsodium-net/PasswordHash.cs
public static byte[] ArgonHashBinary(string password, string salt, StrengthArgon limit = StrengthArgon.Interactive, long outputLength = ARGON_SALTBYTES)
{
return ArgonHashBinary(Encoding.UTF8.GetBytes(password), Encoding.UTF8.GetBytes(salt), limit, outputLength);
}
当我将salt转换为utf8字符串时,哈希函数将失败,因为它们正在检查字节数组的长度,以确保其16个字节。如果我将其转换为ascii字符串,它可以工作,但会产生不同的散列(这是预期的)。
澄清这段代码中的散列部分不是问题所在。找出
tmp
不同的原因,然后saltAsBytes
才是关键。 最佳答案
我认为这里的问题是ArgonGenerateSalt
方法没有返回utf8编码的字符串,它returns completely random bytes。
不能将随机字节解码为utf8字符串并期望它往返。下面是一个小例子,可以看出这一点:
var data = new byte[] { 128 };
var dataAsString = Encoding.UTF8.GetString( data );
var dataAsBytes = Encoding.UTF8.GetBytes( dataAsString );
之后,
dataAsBytes
将是3个字节(特别是2391189)。