22 ms·
How to Safely Store Your Users' Passwords in 2016
- pbreit 11y agoAssuming this is legit (seems like it), mega bonus points for walking through examples on the various platforms/languages.
- josefdlange 11y agoAnyone have a good explanation of why, in the Python example, they recommend `hmac.compare_digest` instead of `==` for comparison? Is there something obvious I'm missing here?
- bradleyjg 11y agoI'm not a python person but it is probably a constant time comparison. If you compare things in such a way that the time it takes to complete increases with increasing prefix match than timing attacks are possible to recover the secret.
- herge 11y ago== in python will stop comparing after the first character mismatch. You can use that fact to test byte by byte your password knowing that the more good characters you have, the longer the comparison will take, which is called a timing attack. hmac.compare_digest is a constant time compare, in that no matter if there is a match or not, it will take the same amount of time.
- Retric 11y agoI don't think that's an issue when your comparing salted passwords. AKA F('Passsword') = Hash('Passsword' xor 'some value') = "123456" F("value") > "123455" which is close, but that does not let you get a 'better' guess. PS: Assuming the Salt is hidden, and the Hash is secure.
- tptacek 11y agoTiming attacks aren't useful against password hashes, but avoiding them is a good habit to be in.
- aidos 11y agoWould it still let you sneak in if the hash was rubbish? Say it was just a simple md5 of the password. If you could do a timing attack you could use rainbow tables of the hashes and whittle down the the possible set of passwords really quickly, right? So if the timing attack has told you that the first letter of the hashed version is 'A' then you find another password from the table that hashes to AAxxx, ABxxx, etc. Obviously that depends on you being able to precompute all the passwords in a consistent way as the hash being used. Along the same lines - could you use a timing attack to figure out a salt? I guess it's near impossible?
- sarciszewski 11y agoYou could potentially leak the first N bytes of a valid unsalted trash hash (e.g. MD5) and then use this information to optimize an offline brute-force attack. The more bytes you leak of the hash, the more you can narrow down your offline attempts and the less subsequent packets you need to fire. I was going to develop this into an exploit tool, called TARDIS (backronym for Timing Attack to Remotely Dispel the Illusion of Security) against, e.g. Piwik, Oxwall, and other products that still use MD5 passwords. The main reason I didn't was: No free time to build it and tune it against the internals of various programming languages' == implementations.
- sarciszewski 11y agoPrecisely what Thomas said. Using == instead of hmac.compare_digest is unlikely to be a source of vulnerabilities in your application, but it's a good habit to get into whenever you touch cryptography. See also: https://news.ycombinator.com/item?id=10345965 https://news.ycombinator.com/item?id=10345965 (pg. 33-36, 42-43 of the PDF) Again consider timing leaks. Many interesting questions: How do secrets affect timings? How can attacker see timings? How can attacker choose inputs to influence how secrets affect timings? Et cetera. The boring-crypto alternative: crypto software is built from instructions that have no data flow from inputs to timings. Obviously constant time.
- deleted 11y ago[deleted]
- wolfwyrd 11y agohmac.compare_digest is constant time whereas == will return as soon as a mismatch is found. The difference in return time can be measured. The key phrase is a Timing Attack[0]. [0]https://en.wikipedia.org/wiki/Timing_attack https://en.wikipedia.org/wiki/Timing_attack
- privong 11y agoFor anyone who reads the comments before clicking the article, the subject is storing your users' passwords, not managing your passwords for a variety of services. I had interpreted it as the latter. A better title might be "How to Safely Store Your Users' Passwords in 2016". (Title is currently: "How to Safely Store a Password in 2016")
- bigbadgoose 11y agogreat, thanks. because i was about to reply with "on a piece of paper in the same place you store your diamonds"
- TeMPOraL 11y agoI'm starting to think that if you're a security-conscious person and understand what's at stake, then the best solution for you would be to simply memorize it. Your mind is the only place from which an attacker can't steal your password without drugging you or beating you up until you give it out.
- 3pt14159 11y agoDifferent loss scenarios. After a bike accident I lost some memory (especially peoples names, but I lost a password I'd set that week). I had no backup and there was no email reset. I just lost access. Now, that ended up not being a huge deal, but had it been say a Bitcoin wallet it would be over.
- danso 11y agoThe main limitation of that is that your passwords are limited to what you can memorize. Which, for most people, is not very much. Even for just one password, never mind for multiple services. I think if you're a pragmatic security conscious person you'd weigh the trade offs...and I thinking of it as just "simply memorize it" opens you up to other problems.
- TeMPOraL 11y ago
- jimktrains2 11y agoOr, we could move to not storing passwords at all, viz client certs and SRP.
- tptacek 11y agoSRP still stores crackable password verifiers, and is tricky to implement safely.
- jimktrains2 11y agoCrackable in what way? Of course the core of it could be upgraded, but the idea is sound. Sounds like you could say the same thing about using a DES-based hash. "Don't Hash! It's weak!" is throwing the baby out with the bath water.
- tptacek 11y agoIn exactly the same way as any other password hash is cracked.
- jimktrains2 11y agoBy iterating over all passwords? That seems like the definition of a good password storage if that's the only way! I mean, you can make the same complaint against anything; it's meaningless by definition. Sure, public-private pairs are more difficult (to impossible) to brute force once they're so long, but srp, bcrypt, pbkdf2 &c are pretty good when you want/need a password. Srp being superior in that your secret never leaves your computer.
- tptacek 11y agoI'm not following you. The whole point of a password hash is to (1) admit only that one brute-force attack, and then (2) to slow that attack down as much as possible. SRP gets you (1), but is inferior to every other modern password hash on (2). SRP is better on (2) than other PAKEs (it's an "augmented" PAKE because it tries to slow down brute force), but password hashes have (2) as their whole objective, and total design freedom. You can combine PAKEs and password hash concepts. But for the purposes of password storage, SRP isn't buying you anything (except for a bunch of possible crypto bugs that will gameover your project). SRP is a bad call for virtually all projects. Or, maybe a better way to say that is, "if you have to ask, don't use SRP."
- rcconf 11y agoIf you're using node.js and you use these hashing methods, your entire server is going to pause for 0.5 seconds on a login because it runs on a single thread. Goodbye to all of your server performance. You can create a worker system, or use a child process to solve this problem, but most of these articles never mention it
- lukev 11y agoI think this says more about node.js than it does about the proper way to secure a password.
- StavrosK 11y agoIt definitely does, and I think that's the GP's point.
- ARussell 11y agoWasn't Node's big draw early on (aside from the fact that it's JavaScript) the fact that everything is supposed to be asynchronous? I'm actually surprised this is a problem.
- mobiuscog 11y agoasynchronous doesn't magically make CPU-intensive tasks faster.
- kornish 11y agoCorrect, but it sure does stop your entire single-threaded process from blocking to the detriment of all other requests.
- corobo 11y agoIt does mean other tasks (e.g. serving pages to visitors) can still be run at the same time as the CPU-intensive task though, like most languages do when it comes to hashing passwords and logging people in
- hellofunk 11y agoIt would be great if, in 2020, or sooner, but probably later, the answer is "don't use passwords any more. They are deprecated components of society."
- jobigoud 11y agoCan you expand on this idea? What type of authentication method would replace it? (One that can't be directly linked to the person obviously).
- jcrawfordor 11y agoI'm optimistic for the use of physical tokens instead of passwords. In my work environment, a lot of authentication is based on physical token possession plus a password just as a guard against lost devices (password validated by the token, not by the service). These kinds of systems aren't technically very complex but there hasn't been a lot of traction for them outside of corporate environments. The result is that they tend to be hyper-expensive, unfortunately. Standards like FIDO and the Yubikey are good first steps at pushing this into the consumer space, although they don't offer on-device PIN validation yet.
- corobo 11y agoI may be confused but how do you validate the password using the token if you've lost it?
- herbst 11y agoI would love a replacement for passwords, but i dont think hardware based solutions are practical enough yet. It is a Gadget more i need to take with me, and even more make sure that it connects with any device i have. The worst part for me would be loosing that thing, in the end i would need alternative login methods anyway to be sure i dont lock myself out. Classic Authy on a Smartwatch would be the simplest method i could live with that comes to my mind.
- 11y ago
- TorKlingberg 11y agoFor some reason the article completely fails to link to libsodium: https://download.libsodium.org/doc/ https://download.libsodium.org/doc/
- sarciszewski 11y ago> For some reason the article completely fails to link to libsodium: https://download.libsodium.org/doc/ https://download.libsodium.org/doc/ The "bindings for most programming languages" link goes to the libsodium documentation, but I'll add a link in more contexts.
- daveloyall 11y agoThe article offers specific advice for Java-without-libsodium, but it offers no such specific advice for Java-with-libsodium. There would appear to be three distinct Java bindings of libsodium.
- sarciszewski 11y ago(I'm not ignoring your comment, I'm currently debating whether to update it to include libsodium example code or to write a separate post for that.)
- obelisk_ 11y agoWrite a separate post and then link to that from your current post. Best of both worlds :D
- AdmiralAsshat 11y agoI had no idea that PBKDF2 had fallen so much in recent years. I still remember the 1Password team extolling its virtues five years ago: https://blog.agilebits.com/2011/05/05/defending-against-crackers-peanut-butter-keeps-dogs-friendly-too/ https://blog.agilebits.com/2011/05/05/defending-against-crac...
- sarciszewski 11y agoCorrection: Scrypt actually uses PBKDF2 internally. (Previously said "scrypt is based on PBKDF2" but that's a loaded statment.) PBKDF2 is an improvement over PBKDF1 (and other naive iterated hash constructions), but attacks got better and better defenses are called for.
- cperciva 11y agoScrypt is based on PBKDF2. No, it really isn't.
- sarciszewski 11y agoI could have sworn it used PBKDF2-SHA256 and Salsa20/8 internally, which is what I meant by "based on".
- cperciva 11y agoIt also uses xor internally, but I wouldn't say that scrypt is based on xor. scrypt does not use PBKDF2 for any PBKDF properties; it's just a convenient arbitrary-length-output hash function. I would have used a sponge if they had been widely available when I created scrypt.
- sarciszewski 11y agoOkay, thanks for the clarification.
- tptacek 11y ago
- Freaky 11y ago> base64_encode(hash('sha384', $password, true)) > ... > The above construction may invite theoretical concerns about entropy reduction (i.e. 72 characters of raw binary without any NUL bytes comes out to about 573 bits of possible entropy, but a SHA-384 hash outputs are clearly limited to 384 bits). Given BCrypt hashes are a mere 184 bits, I don't see how this is a meaningful concern even in principle. If you're brute-forcing search spaces this big you're no longer looking to recover a password, but find a collision.
- sarciszewski 11y ago> Given BCrypt hashes are a mere 184 bits, I don't see how this is a meaningful concern even in principle. This was added in response to a point that a couple people (or perhaps a convincing sockpuppeteer) raised and tried to use to decry the entire article. You're lucky to get 60 bits of information entropy in any given user's password, as is. The "theoretical weakening" here isn't a practical concern: "2^192 security" is still boring crypto.
- pratnala 11y agoDoes Argon2 have an official website and repo or is it just the PHC repo?
- sarciszewski 11y agohttps://github.com/P-H-C/phc-winner-argon2 https://github.com/P-H-C/phc-winner-argon2 is the official repo.
- balls187 11y ago"How to Safely Store a Password in 2016" Don't. Unless it's 100% absolutely necessary. If you must, continue reading on.
- rehevkor5 11y agoThe article inaccurately describes generating a password hash & using it as "storing a password".
- sarciszewski 11y agoThe title has been corrected as of ~half an hour ago.
- rehevkor5 11y agoI still see "How to Safely Store Your Users' Passwords in 2016".
- sarciszewski 11y agoThat's the correction. Given that the audience for this blog post is developers, I feel that the current title is precise enough. People who know about password hashing don't need this advice. People who are storing passwords need this advice.
- balls187 11y agoMy point is simply if you can avoid storing user credentials, avoid storing their credentials. For many services, the most valuable data they contain happens to be the user credentials that the service uses to authenticate the identity of the user. If you assume that users share their credentials across multiple services, if your system is attacked, and you improperly stored their credentials, you've caused way more damage, than the data you were trying to secure. For example, take your run of the mill online todo app. If an attacker got access to the all the todos, vs an attacker got access to the all the todos and all the user passwords (even if securely stored). What is more valuable to an attacker?
- jordonias 11y agoI called my bank the other day and they asked over the phone for my password. This isn't a bank I often use, I only currently have a loan through them so I've never used the login on the website. I said I don't remember setting a password. They gave me a hint about the characters in the password and I was able to remember the password based on their hint. I verbally said the password character by character and they confirmed it. This is an example of how to not handle passwords in 2016.
- nostromo 11y agoName and shame.
- deleted 11y ago[deleted]
- gist 11y agoI don't think you should out them publicly. Are you interested in having them improve their security model [1] or do you want to have what they have they done out in the open so that others can try to social engineer them and their customers might suffer the consequences? [1] If so, tell them about this in a way that will get their attention without causing their customers or them any harm.
- jordonias 11y agoYou're correct. I'll contact them.
- AstralStorm 11y agoAlways have a reasonable response deadline. For a security issue, above 1 month is unreasonable for a small deployment, above 3 months in a huge deployment in my opinion.
- deleted 11y ago[deleted]
- deleted 11y ago[deleted]
- jtwebman 11y agoBad idea to use bcrypt.hashSync in Node.js. I hate that so many tutorials use that one instead of the correct bcrypt.hash with a callback. This is Node.js for that 200 ms where you are hashing that password nothing else runs, no requests, everything stops. Here is the correct way to use bcrypt in Node.js: bcrypt.genSalt(10, function(err, salt) { if (err) return; //handle error bcrypt.hash(clearPassword, salt, function(err, hash) { if (err) return; //handle error // Store hash in your password DB. }); });
- dsp1234 11y agoNote that bcrypt.hash just calls bcrypt.hashSync anyways[0]. So there it's still going to stall exactly the same amount. edit: Looks like it depends on which version you use. 'npm install bcrypt'[1] gives a version which supports true async usage (via V8 async callbacks in native code) 'npm install bcrypt-nodejs'[2] gives a pure JS version which I linked to. Which is the top search result for 'nodejs bcrypt' [0] - https://github.com/shaneGirish/bcrypt-nodejs/blob/master/bCrypt.js#L630 https://github.com/shaneGirish/bcrypt-nodejs/blob/master/bCr... [1] - https://www.npmjs.com/package/bcrypt https://www.npmjs.com/package/bcrypt [2] - https://www.npmjs.com/package/bcrypt-node https://www.npmjs.com/package/bcrypt-node [3] - https://www.google.com/search?q=nodejs+bcrypt https://www.google.com/search?q=nodejs+bcrypt
- serge2k 11y ago> PBKDF2 (nearly everyone except FIPS agrees this is the worst of the acceptable options) is that true?
- tptacek 11y agoOnly in the most technical sense: cycle for cycle, PBKDF2 gets you the smallest amount of protection from that group of password hashes. PBKDF2 is still vastly better than non- password hashes like salted SHA.
- joshreesjones 11y agoYou say that "PBKDF2 is still vastly better than non-password hashes like salted SHA", but is PBKDF2 (with >10,000 iterations using SHA512 and a random salt, for example) secure enough?
- giancarlostoro 11y agoI'm curious if any D developers care to share their approach to this?
- sarciszewski 11y agoI'm part of the Paragon Initiative Enterprises team and have access to edit the blog. If you have any questions (AMA) or would like to suggest any additions, please let me know.
- warrentr 11y agoWe really appreciate the post, thanks! Not a suggestion for this topic, but would love a future post on request signing in 2016 (think HMAC). In particular there are so many JSON REST APIs these days going over HTTPS that it's hard to determine best practices and what's overkill.
- sarciszewski 11y agoThanks for the suggestion, I'll put it on the list. :)
- carlesfe 11y agoHere's yesterday's discussion for the exact same post (maybe the duplicate search failed this time?) https://news.ycombinator.com/item?id=11108481 https://news.ycombinator.com/item?id=11108481
- intrasight 11y agoStoring passwords is like storing credit card numbers - just don't do it
- Justsignedup 11y agoWish there was a site where it lists algorithms and gives a table, and an ability to compare it to x years ago: algorith | fairly safe difficulty (all variables) | very safe difficulty without incurring too much performance cost. pbkdf + sha1 | completely unsafe | completely unsafe pbkdf + sha2 | 100000 | ... pbkdf + sha256 bcrypt scrypt argon2
- tptacek 11y agoPBKDF2-SHA1 is safe. That's the problem with a chart like this. The gradation will go from "completely unsafe" salted hashes to "very much safe enough" with only marginal changes after that. Another problem is that these functions are all parameterized, so the chart needs to capture the safety level at specific parameters.
- sarciszewski 11y agoIt would make for a good interactive "chart", perhaps. Whereby, as long as your sliders aren't all the way to the left, the chart is mostly green.
- Justsignedup 11y agoMy goal was to create a chart of: algorith | a safe set of parameters | a VERY safe set of parameters but needs strong hardware Maybe a 4th column of "unsafe if difficulty is below" This could be something updated yearly or whatever to help people figure out what things they need to move towards. If they see that their currently used settings are below the unsafe line, they will know it's time to upgrade. Example: I use PBKDF2-SHA1 at difficulty of 11k iterations. Is that number still within the "probably okay" list, or is that in the "I can hack any password on your list in 15 minutes"
- latenightcoding 11y agoPerl programmers should try this module: Crypt::ScryptKDF I have been using it for a while now
- eCa 11y agoAnd with DBIx::Class it is almost easier to do it right[1] than wrong. [1] https://blog.afoolishmanifesto.com/posts/do-passwords-right/ https://blog.afoolishmanifesto.com/posts/do-passwords-right/
- jayeshsalvi 11y agoBy not storing them https://medium.com/the-story/signing-in-to-medium-by-email-aacc21134fcd#.fkttu9kdh https://medium.com/the-story/signing-in-to-medium-by-email-a...
- ngrilly 11y agoWhat about occasional delays in receiving the login email?
- dagurp 11y agoThe only problem I see with that is when people change email addresses (maybe they were using their work email and change jobs).
- Nullabillity 11y agoDon't use your work/school/ISP/whatever email. Period.
- melicerte 11y agoThat's an interesting point indeed. When you are fired from your job, you don't often have the time to connect to all our accounts based on your email address to change it. Just checked their FAQ[1] but this does not seems to be covered. Any clue someone? [1] at the bottom of this page: https://medium.com/the-story/signing-in-to-medium-by-email-aacc21134fcd https://medium.com/the-story/signing-in-to-medium-by-email-a...
- x1798DE 11y agoMaybe this isn't practical for some people, but I think it's bad practice to use your work credentials for something you plan to "take with you" when you leave. Best to keep a strict separation of work and personal credentials.
- melicerte 11y agoYes and no. Yes, obviously for your bank account or something that is very personal. But as an IT manager, you could enforce people from your company to use their work email address for accounts that are directly linked to your company activity. For instance, We use a online tracker[1] for Use cases management. When someone leave the company, it does not have access to its email account. Consequently, he/she would no longer have access to our tracker by not having access to its email address. This could rather convenient scheme. [1] Pivotal tracker (who requires password to connect).
- sinatra 11y agoFrom previous discussions about this topic, I had noted down the following best practices: Passwords should be scrypt'ed on client, and then, the server should generate a SHA256 hash of the scrypt'ed hash and store that in DB. - Running CPU & memory heavy scrypt hashing on the client side will allow us to use bigger hashing work-loads. - EDIT: Removing the MITM point, because as many said, that's the job of TLS anyway. - External brute force attackers will have to take the burden of heavy hashing. No DOSing through scrypt. - Storing SHA256 hash instead of scrypt hash on DB means even if DB is stolen, attackers can't use stolen scrypt hashes to authenticate any client. I would love to get others' feedback on this. EDIT: Found the reference: https://news.ycombinator.com/item?id=9305504 https://news.ycombinator.com/item?id=9305504
- vincentdm 11y agoVery interesting. Is there a reference implementation or discussion you can link to?
- sinatra 11y agoI'll try to find the discussion. EDIT: Here's the discussion - https://news.ycombinator.com/item?id=9305504 https://news.ycombinator.com/item?id=9305504
- sarciszewski 11y agoHow are you going to calculate the scrypt hash, client-side? Doesn't that scrypt hash then become the password, from the server-side application's perspective? How are you storing the salt for the user if your server only knows about a SHA-256 hash. > MITM attacks won't get access to unencrypted fields. That's TLS's job. If you, for example, are building a web app and you're delivering Javascript to perform the scrypt calculation, a MitM can replace the code to exfiltrate the user's plaintext password. It doesn't make sense for the threat model.
- sinatra 11y agoVery valid questions. Let me try to answer them and let's see if those answers are valid or not. Yes, the scrypt hash just becomes the password for the server. However, this password is going to be unique and almost impossible to guess. Salting this password on server side doesn't give us any additional benefits. The server can store the salt that the client used, though. Yes, the MITM point was minor. Just another minor security benefit on top of TLS (which takes the majority of the burden of securing against it). So, maybe I shouldn't even mention this point.
- VincentEvans 11y agoSerious question: What about using a Public/Private key encryption to store the password? - Private key is stored in a secure place. Offline for all i care; printed on a piece of paper; memorized and swallowed. - When user creates the account - password is padded with salt, then a public key is used to encrypt it. The resulting encrypted form is stored, along with the salt. - When user attempts to authenticate - the password that is provided is padded with the stored salt, encrypted with the public key and compared to the stored password. Private key is never used when comparing passwords. Never available to the system doing authentication, etc. The only purpose of using a reversible encryption - is to be able to switch to a different authentication provider completely transparently to the user. I've implemented this functionality considering that we may need to switch over to active directory (or some other directory) in place of storing passwords in the database - but never used it, fearful that i would be committing some cardinal crime against proper security practices Thoughts?
- cpitman 11y agoThe more standard way to migrate passwords/authentication schemes is to do it on login. So if you want to switch to scrypt from some other format, wait for them to login, check their password via the old method, then rehash the password with the new method. Store in the database which method was used. If you're switching to a non-password based system like OAuth, make users link their accounts after logging in with their password. If you are going to completely drop the password, then send each user an identifiable link where they can link their account.
- VincentEvans 11y agoThank you for your reply. Interesting you mention intercepting users passwords. Our system already went through a similar transition years ago - when we had to migrate away from NDS (Novell), since we abandoned that technology. In NDS we did not have access to hashes. We ended up having to "MTM" the passwords in opur web app to intercept them before they are sent to NDS and after a successful login store them in the database. To transition our entire user base took a very long time (more than a year), since we had no way to compel the users to login and had to wait until they login on their own volition. Ever since we've been reluctant to lose the ability to recover the passwords. Transition to Active Directory has been on our agenda for quite some time - and having the ability to decrypt the password for this purpose - we can make that happen in short order (AD hashes the passwords, so it will be a one-way operation of course). But the question still stands - is asymmetric encryption strong and secure enough to take place of hashing, assuming the private key is secured? I have not been able to find any relevant sources to answer these questions.
- deleted 11y ago[deleted]
- xs 11y agoLame title. Story talks about storing password hashes and not passwords. I'm still looking for a solution to storing actual user passwords. Scenario: All laptops in the company have a unique local administrator password. How do I manage this effectively as a domain admin?
- jsmeaton 11y agoUse a password manager of some kind. Lastpass is nice, and has an enterprise component that lets you share passwords with co-workers or teams.
- astockwell 11y agoI believe the Ruby example is incorrect: When checking a password's validity, you must use a constant-time comparison or else you are exposing a vulnerability to side-channel timing attacks. There is an open issue in Coda Hale's bcrypt repo about this: https://github.com/codahale/bcrypt-ruby/pull/119 https://github.com/codahale/bcrypt-ruby/pull/119 My stance on posting "best practice" articles is: you must follow all best practices in them. <Edited for clarity>
- sarciszewski 11y ago> I believe the Ruby example is incorrect Unfortunately, there's nothing I can do about that, unless someone can point me to an alternative that uses a constant-time comparison. I've left a comment on the pull request so that, hopefully, it can be merged. > (and likely others) Which others?
- astockwell 11y agoAfter re-reading the others in depth, all other examples appear to use appropriate comparison methods (knowing nothing of the underlying implementations). I've updated my comment to clarify. I see your team is actively posting on the bcrypt-ruby issue #119 as we speak, so I guess I'd say wait for the PR to merge, or manually implement the approach they've outlined to secure compare: https://github.com/codahale/bcrypt-ruby/pull/119/files https://github.com/codahale/bcrypt-ruby/pull/119/files
- Freaky 11y agoAs mentioned elsewhere in the thread, this isn't a "you must", this is a "you might as well". Timing attacks depend on an attacker having control over the hash being compared (e.g. they have a HMAC in a cookie they're sending you, and they can adjust it character by character) - with randomised secret salts and server-side hashing, this isn't the case. The SCrypt example is the one I'm more concerned with. The defaults there are 1MB of RAM and 64-bit salts, both of which could do with increasing. I have an open issue on this: https://github.com/pbhogan/scrypt/issues/25 https://github.com/pbhogan/scrypt/issues/25 As it is, the example would probably be better as this: password = SCrypt::Password.create(usersPassword, salt_size: 32, max_mem: 16*1024*1024) You'll be pleased to know SCrypt::Password#== is at least constant-time.
- PixelB 11y agoI use an ultra secure method for my passwords, it is 100% unhackable. Proprietary Analog Password Encryption Routines.
- sarciszewski 11y agoThat's not very useful for web programmers that are handling their users' passwords, is it?
- damon_c 11y agoI have always been impressed by the way django does it. https://docs.djangoproject.com/en/1.9/topics/auth/passwords/ https://docs.djangoproject.com/en/1.9/topics/auth/passwords/
- movedx 11y agoHashicorp's Vault (vaultproject.io) is also an excellent way of controlling access to secrets and back ends, such as PostgreSQL. It's worth spending the time to learn, implement, and integrate into the security best practices you should already be deploying.
- dogweather 11y agoI believe that the safest way is not to save them. Instead, outsource this to a few select OAuth providers which you and your customers are willing to trust.
- sarciszewski 11y agoWhat do you do if your name is Dread Pirate Rogers and the set of OAuth providers you and your customers trust is "None"?
- dogweather 11y agoHeh, good point.
- jsmeaton 11y agoI agree for the majority of cases. There still exist classes of applications where you can't rely on personal accounts on social sites for auth. Anything that runs behind your firewall for instance. In my particular case, we run some "enterprise software" on behalf of our customers, whose users regularly don't even have a work email address. Our customers are certainly not going to want users to use their own personal addresses. Most of this can be solved with SAML, but it requires all of these old enterprisey stacks to convert their auth systems to be SAML compatible. In the long term though, I think SAML and OAuth will be more prevalent than using passwords everywhere. Are there any OAuth providers established that simply provide email addresses? I feel there's definitely room for a company to setup an OAuth provider that doesn't do anything except provide identity, rather than relying on personal information harvester companies (FB, Google, etc). The hard part would be getting onto the approved OAuth providers list of all the sites that users want access to.
- CM30 11y agoWhat do you do about sites where the users don't particularly likely said providers? Not everyone uses Facebook or Google or Twitter after all, and a lot more would rather use an anonymous disposable account than one tied to an existing identity. There's also the fact said systems seem to be a nice target for spammers. They're popular, so they're often attacked. And because they're often attacked, their anti spam defences don't usually last very long. So any spammer now has a nice way to get an account on near enough any site they like, while with a standalone system, they'd at least have to tailor their attacks to the site in question. There's also the fact it silos much of the internet (or at least user information) within the systems of a few large providers, which gives a significant amount of control to said providers.
- xjlin0 11y agoRuby's argon2 gem is pretty good!
- cm2187 11y agoWhat I find frustrating is the lack of availability of most of these algorithms for the most common platforms (.net, php, java). The author recommendation seems to be driven by availability, not the algorithms own merits.
- technion 11y agoIt wasn't long back, trying to use bcrypt in PHP was an exercise in futility.
- sarciszewski 11y agoIf you're using any of: PBKDF2, Bcrypt, Scrypt, Argon2, then you're fine. Our recommendation is: 1. Use the best option available, but 2. We provided example code in multiple languages for the best one that's widely available
- oliwarner 11y agoDisappointed that the first solution isn't: Let somebody else do it. I know this doesn't apply to banking, etc but 99% of the websites that "require" me to create an account and log in don't need to store primary credentials for me. Please pick a secure implementation of oAuth2 and let people store their credentials wherever the hell they want to. I'm bored of getting hits from "Have I been pwned?"
- sarciszewski 11y agoThis requires your users to trust whichever OAuth providers you decide to integrate with. Sometimes, the set of "trusted OAuth providers" for your users is {}. What then? > 99% of the websites that "require" me to create an account and log in don't need to store primary credentials for me Why are you giving them valuable credentials? Give them a throw-away password (password managers are great for this).
- oliwarner 11y agoI meant OpenID. I literally couldn't see I was saying the wrong thing. Everything you say about OAuth is true. I'm an idiot. I'm sorry for getting so blue in the face. A hybrid between the two (common OAuth-style endpoints and any OpenID endpoint) is the best solution for everybody.
- oliwarner 11y agoYou don't integrate with a provider. You implement the protocol and let your users supply a URL. Layering on popular alternatives (Facebook, Google, etc) help, but use the Stack Exchange model. Let users do what they want to do. That way users can be their own oAuth providers if they want.
- ngrilly 11y agoI thought that Stack Exchange was using OpenID?
- sarciszewski 11y agoMy question was: "What if your users don't trust any of the existing providers on Earth?" It's hard to make a blanked recommendation like that, even for "only 99%" of websites. Neither you, nor the person building the website, has any insight into who the website's users trust. Offer OAuth2 as an alternative to passwords: Great move. Only offer OAuth2 and don't let people create an account: Questionable.
- firelink 11y agoI kind of don't like this article. I think we should be teaching people best practice for securing and storing a password, not simply giving them a library.