Since Django 1.10 the docs have recommended using Argon2. I’m curious how many people do this in the real world as opposed to relying on the built-in solution or switching entirely to other methods such as Okta, etc?
While we aren’t governed by NIST, we do rely upon them for guidance and as a practical matter, defense for certain decisions we make. (It’s a lot easier to defend a position if it has been acknowledged or approved by them.)
As of the FAQ distributed for NIST Special Publication 800-63: Digital Identity Guidelines in March 2022, they have this to say:
NIST considers the security of the hash (one-way) function used in key derivation to be of primary importance, and therefore requires the use of an approved (thoroughly vetted) one-way function in key derivation. … Other algorithms such as ARGON2 are memory- and time-hard, but do not use an underlying one-way function that has been thoroughly analyzed.
Now, this does not constitute a prohibition. They go on to say:
The key derivation function is considered less critical than the one-way function that underlies it, so the specification is less prescriptive in this area and does not specify particular algorithms for key derivation.
(They also say that PBKDF2 isn’t ideal either, but it’s so widely deployed that it’s not practical to require an alternative.)
In a more current publication on comments to SP800-132, multiple people suggested that NIST acknowledge and possibly even approve of Argon2.
So to answer your question, no, we do not.
First thing I do on any new project is configure to use argon2. Even if I’m using auth0/okta/allauth, there’s a chance ModelBackend is still used as a fallback, or that real passwords are still at some point hashed in the db, even if they’re unused.
It’s so easy to set it up these days (there’s even an “extra” so you just pip install django[argon2], then change your HASHERS setting to put argon2 first).
As to the rationale for using it; I suspect it’s good enough to use PBKDF2, but I like being prepared.
Argon2id will (probably) outlast PBKDF2. If the hashes on my site are stolen or accidentally revealed somehow, I’d rather those hashes be the least likely to be cracked possible; once they’re out there, you can’t get ‘em back, so the harder to crack the better.
On that note, the other thing I almost always do is set up a custom password validator to query haveibeenpwned to make sure a password being used isn’t known to be compromised.
That’s true about the “extra.” Makes it very easy to implement. And yes: it seems like a better default, easy enough to implement, so I’ll start doing it more regularly in my own work and also recommending it to newcomers who might not read/remember the docs closely.
I used it once on a personal project, and if I were to start another one, I’d probably use it again. But since I often come into existing projects, I normally leave them on PBKDF2, since there are bigger issues for me to look at.
I don’t think I’ve ever seen a security audit or pentest report say that PBKDF2 is not strong enough.
I’ve used it on all my projects, professional and personal since 1.11, it’s just part of my standard new project set-up.
I’ve migrated a couple across to it from others in the past as well.