kmaragon / Konscious.Security.Cryptography

MIT License
202 stars 20 forks source link

verify Argon2 #21

Closed jedi108 closed 6 years ago

jedi108 commented 6 years ago

how to verify Argon2.Verify(passwordHash, password) ?

kmaragon commented 6 years ago

There wouldn't really be a way to do that with that little bit of information. You wouldn't want there to be. That's pretty poor security. You would need to know the parameters that were used for creating the hash. This is actually part of the security of any hashing algorithm. It gives you more ways to distribute trusted parties.

You would need all of the parameters used for creating the hash:

bool VerifyArgon2Hash(string hash, int parallelism, int memory, int memory, byte[] salt, byte[] associatedData, byte[] knownSecret, string password)

Then you could rehash the password and apply whatever encoding you used to get from byte -> string to see if it matches the hash.

One way I've seen this used generically with pbkdf2 that should translate here with higher dimensionality is:

auth: username / password

step 1: Lookup username in Auth DB. Find Salt, Iterations, MemorySize, KeyServer's ID, and Hash, all of which were generated at the time of creating the entry. step 2: Use a cert auth between servers to ask a KeyServer for the KnownSecret for the ID specified in the user DB step 3: Get any associated data if applicable (might actually be part of step 1) step 4: Instantiate Argon2 with the password as UTF-8 and provide:

With this scheme, even if your Auth DB is hacked, brute forcing the hashes is still virtually impossible without also having taken complete control of the key server(s). And even then, with Argon2, without quantum computing, that process could take as much time as it took for the earth to form and then produce human beings. And even with quantum computing that's likely due to the memory hardness of Argon2.

kmaragon commented 6 years ago

Another scheme that splits things more might use an Api Key. You could SecureRandom generate some bytes for the password and pad them with a Key ID, and many of the Argon2 parameters. For example:

[ 16 bytes ][  4 bytes  ][  4 bytes  ][           x bytes           ]
  key uuid   parallelism  iterations    SecureRandom password bytes

So then your db only has memory size, salt, keyserver id, and the hash, reducing the risk even more of an attacker taking the auth db.

manscrober commented 4 years ago

I would say that the security of argon2 is not based on these parameters and in order to guarantee consistency in password databases, these parameters have to be stored somewhere. The standard example from the argon2 github shows the encoded hash with all inputs and that's the way it's implemented over different bindings as well. The idea of these bindings is, after all, to make this easy to use for less crypto-savvy Developers. Now whoever relies on this binding has to be knowledgable enough to actually know how to store and choose all the inputs properly.