For typical needs, such as passwords and keys, you'll want to use the Argon2i variant, which is slower and provides more protections.
For atypical needs, when you're certain there are no side-channel risks, you may want to use the Argon2d variant, which is faster.
Argon2 has introduction slides here: https://www.cryptolux.org/images/c/c5/Rwc-slides.pdf
> Argon2 ensures that both defenders and attackers hash passwords on the same platform (x86)
Do they simply mean that currently the most cost effective platform to deliver the necessary computation and memory is x86?
I'm having trouble believing that it is either achievable or desirable to design a password hash that's only efficient on one architecture.
I'm having trouble believing that it is [...] desirable
I'm having trouble believing that it is [...] achievable
Why is this desireable?
This is desireable because your server has a CPU. Your attacker has a CPU, a GPU, perhaps an FPGA, and could possibly manufacture a custom ASIC. You do not want the attacker to be able to cost-effectively bruteforce on any of these platforms any more efficiently than a single CPU core can.
This makes password cracking difficult, and it also means we do not need to have absurd CPU runtimes for our hash, a handful of milliseconds is sufficient. (More is of course better, and for a single user system a delay of half a second isn't noticeable.)
What would occur if we did not design password stretching functions that had this property?
We would end up in the situation we have now, where nonstandard hardware computes hashes faster than we can, and thus instead of taking (a few miliseconds * number of possibilities) it takes (smaller amount of time * number of possibilities). This is undesireable.
This is also why you should never use a typical fast cryptographic hash function like SHA256, SHA3 or RIPEMD160 to hash passwords. This is also why PBKDF2 is considered less secure than say scrypt.
Does this mean that one has to choose between protection against side-channel attacks and protection against GPU cracking? While not the "safest", how safe is Argon2d against side-channel attacks, and vice-versa? Any advice on making this choice?
(It's late here so I haven't read the paper yet. Apologies if this is all covered in there.)
"Argon2i uses data-independent memory access, which is preferred for password hashing and password-based key derivation. Argon2i is slower as it makes more passes over the memory to protect from tradeoff attacks."
"Argon2d is faster and uses data-depending memory access, which makes it suitable for cryptocurrencies and applications with no threats from side-channel timing attacks."
The IETF draft is here: https://tools.ietf.org/html/draft-josefsson-argon2-00
Yes. Argon2i is still resistant against GPU cracking, however with advanced techniques some speedup might be acquired. Argon2d is really GPU unfriendly. The paper explains:
> Should the memory addressing (indexing functions) be input-independent or input-dependent, or hybrid?
The first type of schemes, where the memory read location are known in advance, is immediately vulnerable to time-space tradeoff attacks, since an adversary can precompute the missing block by the time it is
needed . In turn, the input-dependent schemes are vulnerable to side-channel attacks , as the
timing information allows for much faster password search.
And the recommendation from the paper:
> Argon2 has two variants: Argon2d and Argon2i. Argon2d is faster and uses data-depending
memory access, which makes it suitable for cryptocurrencies and applications with no threats from side-channel
timing attacks. Argon2i uses data-independent memory access, which is preferred for password hashing and
password-based key derivation.
btw. Colin Percival (creator of scrypt) was part of the committee.
yescrypt, one of the recommended finalists, is an improved/fixed version of scrypt.
You can throw a dart to pick any of the password hashes, including PBKDF2 (the worst of them), and you'll be just fine.
When a user attempts to log in, you hash the password they submitted with whatever's in that user's `hashing_scheme`. If the password was incorrect, fail early.
If the password was correct, and this user's `hashing_scheme` value is different to the application's `current_hashing_scheme`, you rehash the user's password (that you got via the POST request or otherwise) with the new scheme, update the `password_hash` and `hashing_scheme` value in the database.
This is just one way to do it, which is how Django performs hashing scheme migrations IIRC.
Once the user has logged in successfully, you can replace new_hash(old_hash(password)) with simply new_hash(password).
This is less useful for optimistic upgrades like bcrypt->argon2i, but is absolutely critical if you find yourself taking over responsibility for a database that has a password column full of, say, MD5s.
Waiting for each and every user to log in to upgrade those vulnerable hashes is suicidal.
For example, Django currently stores its passwords in a single database column as
As far as I can tell this is the best possible service you can offer to the users whose long-ago passwords you're storing, short of deleting their passwords entirely. Throwing away the earlier version and replacing it with the argon-wrapped version can't hurt them, and will almost certainly help.
(Usual caveats apply about not doing things that add complexity if you don't need it.)
http://php.net/manual/en/function.password-needs-rehash.php (PHP >= 5.5)
Are you sure? And if so, can you convince me as to why you are so sure?
Wrapped hashes could have other side effects for probing non-hacked sites -- for example, attackers could probably figure out which chain a user has based on timing, which would let them narrow down a bit when the user last logged in. Hash chains could also theoretically reduce the total output space for the final hash, making it easier to brute force a password through the login form of a non-hacked site. I don't consider either of those likely to matter, but you might.
* Fully expire the accounts (and send emails asking them to reset their password)
* If they successfully login to their account and you have the plain text password, you can re-hash that using argon2i.
* Have them reset their password on next sign in before allowing them to do anything.
* Let the user know their account has less security than it could, and they can upgrade the security by changing their password.
Afaik, there is nothing you can do to upgrade their passwords, modulo argon2'ing the result of another hash function - I am simply too unclear on the safety of this approach so I don't do it.
I.e. store the result of `argon(bcrypt(md5(password)))`
Any security drawbacks to this?
The top voted answer has a comment that's spot on:
I would offer the opposite argument: if one uses a single hashing function which has a 0.1% chance of having a discoverable weakness that would allow an attacker to speed it up by a factor of a million, there will be a one-in-a-thousand chance that an attacker will be able to gain a million-fold speedup. If one used three independent functions, each of which had a 0.1% chance of allowing such a breakthrough, there would be a 0.3% chance of an attacker being able to achieve a 33% speedup, a 0.0003% chance of an attacker getting a 66% speedup, and only a 0.0000001% chance of an attacker... – supercat Jul 13 '15 at 17:21
...getting a million-fold speedup. I would consider the possibility of an attacker getting a 33% speedup as inconsequential compared to the reduction in the probability of the attacker getting a 70%-or-better speedup. – supercat Jul 13 '15 at 17:22
In short: You lose on average (but who care?) but you reduce the risk of catastrophic failure.
"A memory cost, which defines the memory usage, given in kibibytes "
Can't read any more. I'll find something else.
The evaluation of which password-hashing function to use probably should not be based on the simplicity of language used in their description.
Even if you disagree on how proper it is, that seems like an extremely small and unimportant qualm.
Use of 'kibibytes' and 'KiB' reflects a fundamentally wrongheaded view of the world, either unserious or too-serious, which shouldn't be taken seriously.
When doing science, is it inappropriate to distinguish between the numbers 1000 and 1024?
Of course not! In computers, 'kilo-' means 1,024; everywhere else it means 1,000. This is a simple rule; network-device and hard-drive manufacturers are just wrong when they violate it.