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:
- Use dumb brute force to try and find a preimage of one user's passwords.
- 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!).