I always say the best piece of advice on this is, "Don't store passwords." Like shown in other comments, the landscape of what should be used changes frequently. Truthfully, I haven't had to write anything that stores passwords for several years, and until now I hadn't heard of Argon2. That's frightening to me and shows how far out of the game I am now. Finding a trusted 3rd party who's responsibility is to stay on t…
How To Safely Store A Password (2010)
21–30 of 65 posts
Re: How To Safely Store A Password (2010)
#22OWASP has nice document: https://cheatsheetseries.owasp.org/cheatsheets/Password_Stor...
It boils down to this:
> Bcrypt is the most widely supported of the algorithms and should be the default choice unless there are specific requirements for PBKDF2, or appropriate knowledge to tune Argon2.
Re: How To Safely Store A Password (2010)
#23Bcrypt doesn't have memory-hardness, so has high susceptibility to ASIC attacks. In particular, it incurs the same or lower cost factor on the attacker than the user. More recent designs such as scrypt and Argon2 force high memory usage as well as computation time, incurring little cost on the users but making ASIC and GPU attacks significantly less cost-effective. Of course, any of these will still give better prote…
Is there any scrypt or argon2 implementation for nodejs that has as nice an api surface as the bcrypt package? Specifically, it will generate a salt for you (included at the beginning of the generated hash). This has the great properties of: can't forget to use or store the salt; use a weak salt; or forget to use the time-safe compare function. I want to minimize the number of footguns available to the person coming…
Here is an scrypt just in JS[1]. It will also run in the browser, if you need to hash client side for some reason. On node, it will use the built in crypto api which IIRC is a wrapper around openSSL so perf should be native. I'm not a big fan of the API, you have to concern yourself with buffers and normalization. Maybe that is important for non-latin alphabets? I don't actually know, I'm too anglo-centric.
Then there is good ol bcrypt[2]. Certainly the most mature, it has been around a while. Like [0], it also uses a native module with node-gyp.
All three support async/await so you can avoid blocking the event loop during expensive hashing operations. I should note I haven't really used any of them. I was just curious so I did some googling.
Based on your criteria, I think [0] fits the bill best. Very hard to forget the salt, as it is generated by default and stored with the hash.
I'm always really curious about other people's code, so I hope you don't mind me asking: I typically use a library/framework that handles details like password hashing. That said, sometimes i like to avoid libs and really understand every aspect. Can I inquire about your stack? Are you using express or koa or anything like that?
[0] https://github.com/ranisalt/node-argon2
Re: How To Safely Store A Password (2010)
#24Bcrypt doesn't have memory-hardness, so has high susceptibility to ASIC attacks. In particular, it incurs the same or lower cost factor on the attacker than the user. More recent designs such as scrypt and Argon2 force high memory usage as well as computation time, incurring little cost on the users but making ASIC and GPU attacks significantly less cost-effective. Of course, any of these will still give better prote…
Is there any scrypt or argon2 implementation for nodejs that has as nice an api surface as the bcrypt package? Specifically, it will generate a salt for you (included at the beginning of the generated hash). This has the great properties of: can't forget to use or store the salt; use a weak salt; or forget to use the time-safe compare function. I want to minimize the number of footguns available to the person coming…
const scryptParams = { logN: 15, r: 8, p: 1 };
async function hashPassword(password: string): Promise {
const password_hash: Buffer = await scrypt.kdf(password, scryptParams);
return password_hash.toString("base64");
}
async function verifyPassword(hash, password): Promise {
return await scrypt.verify(Buffer.from(hash, "base64"), password);
}Re: How To Safely Store A Password (2010)
#25Why would you pick one over the other? Or are both "pretty much fine" for most workloads and a casual user shouldn't worry too much?
Re: How To Safely Store A Password (2010)
#26Re: How To Safely Store A Password (2010)
#27Earlier quoted context omitted.
Counterpoint: A dedicated "authentication party" is a privacy nightmare and a single point of failure. See https://news.ycombinator.com/item?id=25091420
Very true, there are drawbacks to using 3rd party authentication and I think a good (at least) middle ground is to purchase a hosted appliance that handles storage and authentication. Of course if you are a large organization that can hire people who do know what they are doing, you are golden. Sadly, these are not the companies that I generally interact with.
Another option more on the cheaper side would be a library that handles algorithm selection and migration in a "black box" way. I.e. the public interface is only `db.put(user,newPass)`, `db.compare(user,suppliedPass)` and maybe something like `db.doMaintenance()`. You would need to handle storage yourself in that case but I don't see the downside of this when you are storing your users' data anyways. I'm not aware if such a library exists though.
Re: How To Safely Store A Password (2010)
#28Earlier quoted context omitted.
Counterpoint: A dedicated "authentication party" is a privacy nightmare and a single point of failure. See https://news.ycombinator.com/item?id=25091420
Very true, there are drawbacks to using 3rd party authentication and I think a good (at least) middle ground is to purchase a hosted appliance that handles storage and authentication. Of course if you are a large organization that can hire people who do know what they are doing, you are golden. Sadly, these are not the companies that I generally interact with.
https://news.ycombinator.com/item?id=25212694
What hosted appliances offerings have you taken a look at?
Re: How To Safely Store A Password (2010)
#29With password storing, you want to cover your ass. One way to do it is follow guidelines of known authority, e.g. NIST or OWASP. OWASP has nice document: https://cheatsheetseries.owasp.org/cheatsheets/Password_Stor... It boils down to this: > Bcrypt is the most widely supported of the algorithms and should be the default choice unless there are specific requirements for PBKDF2, or appropriate knowledge to tune Argon2…
Re: How To Safely Store A Password (2010)
#30Imagine every device has a cookie/token with 256-512 CSPRNG bytes which uniquely identify it. The server uses this as the exclusive means of authentication. For sensitive application scenarios, an in-app PIN mechanism can be used as a soft protective measure (e.g. Robinhood mobile apps use this). The device you initially sign up on can be used to activate additional devices by way of scanning a QR code, offline recovery codes, SMS, etc.
This model makes it so that a user has no username or password to remember. They just need to make sure they have a backup device and/or offline recovery options available. I find that side-stepping the problem altogether might be the best solution for all involved. Users loathe remembering passwords. Developers screw up password hashing constantly. Malicious actors should grow to strongly dislike this approach.
This also provides a much stricter chain of custody over how additional devices are added to an account. You have to already have a trusted device to bring another. Making the "What you have" (device) the first factor, and the "What you know" (i.e. pin code) the second factor seems to work out a lot better looking forward.