4 ms·
This isn't "Doing it right". A. Your Salt should ALWAYS include a feature you have to store anyway about the user that would be unique to your service. Use mul
by drakaal 13y ago
This isn't "Doing it right".
A. Your Salt should ALWAYS include a feature you have to store anyway about the user that would be unique to your service. Use multiple if you need to. This applies no matter what Hash mechanism you use. Also include a calculated value that isn't stored.
Example:
UserName + PassWord + User ID + CreationDate + <Numerals from a Base64 encode of the users first and last name>
Don't put all of this in the same database, so that a Data Breach won't give an attacker all the data they need.
No Rainbows for that combination. If a user changes their user name update their hash.
This is why in good services you have to provide your password when changing your username even when you are logged in.
B. To Validate the User Name:
Step 1 is always "Check that the password meets your password Criteria. If you have a requirement that passwords are 6-24 characters, contain 1 upper, one lower, and one digit, then make sure the password has those before you do anything else. No database lookups for bad passwords. No running bcrypt on a 4 megabyte section of post data. This is how you keep Denial of service attacks from crushing your service.
C. MD5 and Sha1 are only bad because there are rainbows for them, and because you can calculate every possible combination of values for a user/pass quickly if you know a single user/pass in the system you can calculate the salt methodology if you have access to the source code as well.
I won't tell you to use either of these, but if you lose your source code, and two databases worth of data so they have user, pass, and user data, you did something else horribly wrong, or it was an inside job and nothing would have saved you. (bcrypt is expensive if you have millions of users a day logging in and not any more secure if you did the other things above.)
- sk5t 13y agoIMHO this is all unsound advice. No sane system follows the "store the data in multiple places" design; you'd need to pull it all back together to validate the password anyway, and a breach is extremely likely to compromise a system that can do exactly that. Similarly, creating a salt from a calculation rather than, say, taking 128 random bits, is not going to help, nor is depending on the secrecy of the source code ever a prudent choice. It will certainly produce less entropy than the latter, will not produce a different salt across password changes, and is just very, very hacky.
- micro-ram 13y agoI agree with sk5t. You can't count on the source to stay secure in a breach. It only adds unnecessary complexity without adding security. You are simply adding length to the password with your own key lengthening algorithm using values that are still in the database or source. You might think your clever (UserName + PassWord + User ID + CreationDate + ...) function adds strength because the current cracking tool doesn't have your clever function. This clever function can be easily added to the cracking tools thus rendering your clever function useless. What you failed to do was actually add a secret that you can guarantee to keep secret even when the database and source are breached. This is why a secure hardware device like the YubiHSM is recommended as the secret is never revealed even in a breach.
- drakaal 13y agoA calculated value means you need source to figure it out. Only PHP and JS/Node scripters assume that their source isn't safe in an attack. The rest of us assume that our compiled code is safe. (Over generalization, but if people can get your source code basically there is zero you can do to keep them out) Storing data in more than one store is a best practice. Your random 128 bits have to be stored somewhere. That means an attacker needs only the database, not the source. In any large scale environment you likely have multiple machines. When a machine gets taken out of service at your hosting provider your database might still be on it when it hits the dumpster. If your source code is on another machine it doesn't matter. The same is true of the Private User Data and the passwords. two locations means you need two breaches to do anything.
- mistercow 13y ago>A calculated value means you need source to figure it out. As I mentioned in my other post, it really doesn't. Using a calculated value means that the entropy of your salt is only as high as the values used to calculate it. >Only PHP and JS/Node scripters assume that their source isn't safe in an attack. So, the vast majority of websites. >The rest of us assume that our compiled code is safe. Why would you assume that? >if people can get your source code basically there is zero you can do to keep them out If people have your source code, and your passwords are stored properly, they aren't going to have any easier of a time cracking them. >Your random 128 bits have to be stored somewhere. That means an attacker needs only the database, not the source. The whole point of a salt is that it doesn't have to be secret.
- mistercow 13y ago>Your Salt should ALWAYS include a feature you have to store anyway about the user that would be unique to your service. What is your rationale for this? Is your concern is that a random salt will accidentally collide? With a 128 bit salt, there is a one in a million chance of a collision occurring in a set of 26 quadrillion. >UserName + PassWord + User ID + CreationDate + <Numerals from a Base64 encode of the users first and last name> That is just incredibly low entropy compared to a random string of bits. If you do this and use (as you suggest is just fine further down) MD5 or SHA1, you are begging for disaster if your site is worth attacking. >MD5 and Sha1 are only bad because there are rainbows for them Wrong. MD5 and SHA-1 both have significant vulnerabilities. >bcrypt is ... not any more secure if you did the other things above Insanely, completely, ridiculously wrong. MD5 and SHA-1 are stupid fast. A GPU-based cracker can try 5.6 billion MD5 hashes per second, and 2.3 billion SHA-1 hashes per second. If you're using a long random salt, you might hold out for a while after a data breach before all of your passwords are cracked. If you derive a low-entropy salt the way you explained above, you'll be completely boned.
- thirsteh 13y agoThis is all terrible advice. Please stop giving it.