cod*_*fun 6 c# hash encoding character-encoding
我正在使用libsodium的.net端口.哈希生成函数有两种形式,一种接受字节数组,另一种接受字符串:
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)
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是两种形式在输入值相同时产生相同的哈希.
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);
Run Code Online (Sandbox Code Playgroud)
任何带有"PasswordHash"的东西.是libsodium而不是我的代码.
从上面的代码,当我从一个字符串转换它然后回到字节数组的字节数组.字节数组数组总是不同的长度.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);
}
Run Code Online (Sandbox Code Playgroud)
当我将salt转换为UTF8字符串时,散列函数将失败,因为它们正在检查字节数组的长度以确保其16字节.如果我将它转换为ASCII字符串,它可以工作但产生一个不同的哈希(这是预期的).
澄清此代码中的散列片不是问题.弄清楚为什么tmp不同saltAsBytes是关键.
我认为这里的问题是该ArgonGenerateSalt方法不返回 UTF8 编码的字符串,它返回完全随机的 bytes。
您无法将随机字节解码为 UTF8 字符串并期望它进行往返。看看这个问题在哪里爆发的一个简单例子是执行以下操作:
var data = new byte[] { 128 };
var dataAsString = Encoding.UTF8.GetString( data );
var dataAsBytes = Encoding.UTF8.GetBytes( dataAsString );
Run Code Online (Sandbox Code Playgroud)
此后,dataAsBytes将是 3 个字节(具体为 239、191、189)。
| 归档时间: |
|
| 查看次数: |
1720 次 |
| 最近记录: |