I just started using the libsodium port for .net today and the output length parameter kind of confused me (I'm using the argon2i implementation).

With my limited exposure to hashing, whatever hash algorithm I've used have always returned a constant bit length (for example MD5 & 128). By default it returns 128 just like MD5 which suprised me. I always equated length with strength (though I realize there isn't a 1 to 1 correlation in every case).

Then comes the question with a variable length output what should I choose :). With argon2 are increased bit lengths really going to be that much more secure? I arbitrarily chose 512 bits but I don't know if that's good or not.

A second, but a little unrelated question, do you think you should store the parameters (that can change the hash) in the database along with the password & salt. Examples would be opsLimit, memLimit, outputLenght, etc...

  • More is always only better until a limit is hit... – SEJPM Aug 8 '16 at 19:05
  • 1
    @SEJPM so for Aargon2i do you think 128 (the default) is ok or would what i chose (512) be better? I don't know what that "limit" would be with this specific algorithm. – coding4fun Aug 8 '16 at 19:10
  • You might take into account how many users you might have. Storing many 512 bit hashes will consume more disk space then 128 bit ones. Possibly not a concern given the price of storage these days and how many users you may actually end up with, but maybe something to consider. – Ella Rose Aug 8 '16 at 19:56
up vote 14 down vote accepted

You need to consider the weakest link property: a security system is never stronger than its weakest link. Since Argon2 is a password-based function, the weak link here is going to be the strength of your users' passwords. Choosing a longer output length doesn't help if the passwords' entropy is lower than that.

Think of it this way: if the hash function is secure, the attacker has two ways to attack the passwords:

  1. Use dumb brute force to try and find a preimage of one user's passwords.
  2. Use knowledge about user habits to guess more likely passwords ahead of less likely ones.

Longer output may make #1 harder, but once you make #1 hard enough then #2 becomes the easy path and attacker will just try that. So Argon2's authors' recommendation of 128-bit hashes sounds fine, because the only circumstance in which the 128 bit output would be the limiting factor is if your users' passwords were crazy entropic, like:

  • ASCII printable uniformly random passwords of length 20 or more (6.6 bits/character);
  • PINs of 40-digit length or more, chosen uniformly at random (3.3 bits/digit);
  • 11-word or longer Diceware passphrases (12.9 bits/word);
  • 12-word or longer XKCD "correct battery horse staple" passwords (2,048 word dictionary, words chosen uniformly at random).

If your users could be counted on to choose passwords that strong, you wouldn't need a specialized password hash function in the first place!

A second, but a little unrelated question, do you think you should store the parameters (that can change the hash) in the database along with the password & salt. Examples would be opsLimit, memLimit, outputLenght, ect...

Yes, you should store them. Note for example that the Argon2 command line utility (which is available from the Argon2 repo) produces verification tags that integrate it (the "Encoded" field from this example from the link):

$ echo -n "password" | ./argon2 somesalt -t 2 -m 16 -p 4 -l 24
Type:           Argon2i
Iterations:     2
Memory:         65536 KiB
Parallelism:    4
Hash:           45d7ac72e76f242b20b77b9bf9bf9d5915894e669a24e6c6
Encoded:        $argon2i$v=19$m=65536,t=2,p=4$c29tZXNhbHQ$RdescudvJCsgt3ub+b+dWRWJTmaaJObG
0.188 seconds
Verification ok

Thinking about this some more, I think I understand why I'd be confused if I was in your position. If the default 128-bit length is fine, and making it longer doesn't really offer more security, why does the function allow me to choose a longer output length?

Well, the reason is that Argon2 has two distinct uses:

  • Password verification
  • Key derivation

Long outputs are of no use in password verification, as I explained above, but of great use in the key derivation case. An example situation where you want something like that is password-based encryption where you're doing something like encrypting a file with AES-256 but, instead of making the user manage raw AES keys, you try to be friendlier and let them use passwords instead. This is, for example, how GnuPG's symmetric encryption mode works (albeit it doesn't use Argon2).

In this case, since your cipher needs 256-bit keys then you need the ability to generate 256-bit keys from your users' passwords. So the selectable output length allows you to match the requirement.

Note that the weakest link property still applies here, so in that scenario even though you'd be using 256-bit encryption, the password would still be the weakest link. What the longer output length allows you to do is to match a technical requirement imposed by the 256-bit cipher, and offers your users the option of choosing passphrases that are effective up to that security level—which very few will do (e.g., a 40 character random ASCII password!).

  • Great answer. The name of the encoded form is Modular Crypt Format, which is a sort of semi-standard for password-hash storage. It would be a good idea to use libsodium's ArgonHashString to get (I hope) exactly the same format. – otus Aug 9 '16 at 6:49

Yes, absolutely store the parameter values used along with output. That gives you crypto agility, so that you can easily change the values later and still have easy compatibility with the existing values.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.