Switch to Argon2

Continuing discussion from this GitHub ticket.

I am aware of Argon2 and it’s benefits over PBKDF2, however, since bitwarden is a cross-platform application that is written on many different languages/frameworks we must use an algorithm that is a standard. PBKDF2 has native implementations on all platforms that we deal with. Argon2 is relatively young and is not yet widely implemented. If we were to use Argon2 we would have to rely on unproven third-party libraries.

Libsodium supports Argon2 and there are bindings for .NET, Java, and Swift. There are also transpilers for JS and WebAssembly.

Users are terrible at choosing passwords and your servers will inevitably get breached.
Between repurposed cryptocurrency mining clusters, probabilistic word lists, and three-letter-agencies plowing hundreds of millions into custom ASICs … your key derivation function is the single most important aspect of your security model. Switching to Argon2 would yield an immediate 3x improvement against brute force attacks on generic GPUs and 10x or more against ASICs.

This is a must have and should be a priority for bitwarden

No news about this?
KeepassXC has it and it’s open source, can’t be that hard.

Just a guess, but I would assume that PBKDF2 (or SHA256) has hardware support which may be required for good performance while other algorithms don’t. This may be especially relevant on mobile

i’m going to quote 1password’s security whitepaper for this, as it explains perfectly why most almost every password managers chooses PBKDF2 over Argon2:

The choice of PBKDF2-HMAC-SHA256 as our slow hash is largely a function
of there being (reasonably) efficient implementations available for
all of our clients. While we could have used a more modern password hashing
scheme, any advantage of doing so would have been lost by how slowly it
would run within JavaScript in most web browsers

this is why it’s perfectly doable for Keepass, being a native desktop app only (and mobile C#/java ports), but unacceptable for BitWarden


But I guess it won’t be a problem if you install a binary in your system (like lastpass does but for other purposes) or if you have a mobile app.
If it takes 10 secs in javascript and 2 secs with the binary I can live with that just in order to have a better security.

Bitwarden has a C# and JavaScript codebase and while there is a native PBKDF2 implementation available in the browser, there are C#, JS, and WASM ports of Argon2. They could split the hashing, with X rounds of PBKDF2 in the browser and X rounds of Argon2 on the server.

Hell, I would advocate setting up GPU instances just for handling the key derivation load. When combined with hash caching, you would really be giving password crackers a run for their money!

PBKDF2 isn’t even as good as bcrypt or scrypt so absolutely it should moved away from and since Argon2 has been designed from the ground as the next-generation key-derivation function with industry backing, Bitwarden should switch to it as soon as is reasonably possible.

Still no news on this huh? A little disappointed admittedly.

@kspearrin any news about this? is at least in the roadmap?

there are C#, JS, and WASM ports of Argon2.

See how well these run on keeweb compared to the native versions used by keepass2
encrypting a database with a 1 sec delay on Argon2 set by keepass2 take over 10+ seconds to decrypt in the browser, which is unacceptable.

I’ve created a (planned to be temporary) fork at https://github.com/michaelsmoody/bitwarden-jslib-argon2. If you would like access to help move to Argon2, let me know. The goal is simply to do the work, and create a PR for upstream, rather than being a permanent fork.

There’s already a FFI implementation for node. Assuming you use “sane” defaults, which timings the user will be against?