I am using the .NET port of libsodium . The hash generation function has two forms: one that accepts byte arrays, and one that accepts strings:
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)
I am having a problem with both forms producing the same hash when the input values ββare identical.
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);
Anything with "PasswordHash". this is libsodium, not my code.
From the code above, when I convert it from a string and then back to a byte array, an array of bytes. An array of byte arrays always has a different length. ArgonGenerateSalt() creates an array of bytes of length 16. When I convert it from a string above it altogether ~ 30 (each time each time due to getting different salts).
Why am I converting to UTF8? Because this is what they do inside: 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); }
When I convert the salt to a UTF8 string, the hash function will not work, because they check the length of the byte array to make sure its 16 bytes. If I convert it to an ASCII string, it works, but creates another hash (which is expected).
To clarify the hashing in this code, this is not a problem. Finding out why tmp is different, then saltAsBytes is the key.