When updating a user record (id, username, password, salt), is it wise to also create a new salt for this record or is there no security disadvantage in always using the same salt no matter how often the user changes his password?
There is no (or at best minimal) security advantage to changing the user's salt so long as each user's salt is different and the user is not being specifically targeted.
The point of the salt is 1) to make pre-computing possible hashes harder and 2) to keep it from being apparent that different users are using the same password. Neither requires that you change the salt.
That said, it certainly doesn't hurt to change the salt as long as you make sure the new salt is unpredictable.
If you change the user salt, when the poor user change his username or anything else except the password, you will endup with a wrong hashed-password salt combination.
There is no reason to change the user salt as described from Old Pro but if you want to change it some time do it only when the user change his password.
Are you using the salt for other entries than the password? In this case you could not change the salt without rehashing all entries using this salt. There are easier solutions than storing a salt per user though.
Most implementations of hash functions for passwords (for example PHP's BCrypt implementation), will automatically generate a new secure salt per hash-value, and will return the used salt as part of the hash-value. So there is no need to store the salt separately, and every time you calculate a new hash-value, the function will generate a new salt anyway.
So yes, it is a good thing to create a new salt for every hash calculation, especially because it can be even easier than storing the salt separately.
Related
So I've been looking at hashing passwords in vb.net and came across this thread (https://security.stackexchange.com/questions/17421/how-to-store-salt/17435#17435) and it showed about the salt only increasing the time to make brute force attack if the salt is known to the intruder as they need to make a new rainbow table. Could this be made more secure by making the salt a hash of the plaintext?
As an example to hash "plaintext" but adding a salt the string, this salt then being a hash of "plaintext" making "32nfdw213123" as example then hashing the total "plaintext32nfdw213123". In this case the salt is different for every value used but when used for verification doing the same process to a correct check string should produce the same salt and therefore the same hash value and verify. Is this actually more secure?
Thanks
TLDR: not really.
Longer answer:
Let's say some baddie has your database with all the passwords in it. He can now start brute-forcing passwords. Your goal is trying to make the brute-forcing as hard as possible.
So, theoretically, given that he has your database, he probably also knows how you're hashing your passwords (remember that security through obscurity is a bad form of defense). Your salts are no longer random, so our baddie can create a new rainbow table.
I have big database with user and passwords in sha256 hash. Now I write new version and I want to use sha256+salt. Is there a way to convert same passwords with sha256 to sha256+salt and have no trouble with login?
Surely it is a good idea to make your password hashes more safe, but using a salted SHA-256 is the wrong way to go.
Best practise is to use a password hash function with a cost factor, which allows to control the necessary time to calculate a hash. Good algorithms are BCrypt, SCrypt, Argon2 and PBKDF2. In another answer I tried to explain how the switch to a new algorithm could be done.
The problem with the fast hashes like SHA-256 is the unbelievable speed of GPUs, one can brute-force about 3 Giga SHA-256 per second with affordable hardware.
The way to salt and hash a password is to take the plaintext password, add the salt to it and THEN hash it. When you have an existing password database already sha256-hashed you don't have the plaintext passwords, and you can't easily get them back in plaintext once hashed (which is a good thing).
What you could do instead would be to take the passwords in their current form, sha256 hashed, add the salt and then hash them a second time - or better: many times, with better hashing algorithms.
The function to verify the password would then repeat those steps to check that the password is correct. Assuming the second hash is just sha256-hashing once to make the example clearer, though it's not sufficiently secure:
step1 = sha256(plaintext_password)
password = sha256(step1 + salt)
If you really want to avoid working on top of your existing hash you could create a new table of users where you process passwords in the new way from the beginning, and then gradually migrate user's passwords over to the new table as they log in with their plaintext passwords, and remove them from the old table.
A third solution could be to deactivate all the old accounts and require them to change their passwords before they can sign in again, via fx. e-mailing them a link to change their passwords.
Makes sense?
That said you will get more qualified answers at https://security.stackexchange.com . For instance I just found this question on why salt->sha256 hashing once is insufficiently secure, and another one here on how to process passwords for more secure storage.
I've read on SO (and from other websites found on Google after I tried to look into it a little bit more) that the correct secure way to store passwords in a database is to store the hashed + salted value of a password. On top of that, the salt should be different for each user so hackers can't do harm even if they have the encrypted values.
I'm not quite sure what salting means. From my understanding, you hash the password, then you use another value that you hash (the salt) and combine those two together so the algorithm to retrieve the original password is different for every user.
So basically, what I'd have to do is hash a password, then use a different hash on a different value for each user (ie: the user name or email address) and then I can do a simple math operation on those two values to get the encoded password.
Is that correct or did I just not understand anything about password hashing + salting?
A simple explanation or example would prove to be helpful as the sites I've found don't quite explain clearly what salting a password is.
Edit: After reading comments and answers left so far, I understand that I didn't really understand what a salt was because I'm missing some key concepts and I was making false assumption.
What I'd like to know is: how do you consistently get the same salt if it is randomly-generated? If the salt is stored in the database like some people have mentioned, then I can see how you keep getting the same salt, but that brings another question: How does it make the passwords more secure if anyone with access to the database have access to the salt? Couldn't they just append the (known) salt to all the passwords they try and the result would be the same (bar some minor time loss) than not having one at all?
Let me try and clarify a little bit with a somewhat oversimplified example. (md5() is used for example purposes only - you should not use it in practice.)
A salt is just a random string of characters that is appended to the password before it is hashed. Let's say you have the password letmein, and you hash it like this...
echo md5('letmein')
...you'll get the output 0d107d09f5bbe40cade3de5c71e9e9b7. If you google this, you'll get a number of pages telling you that this is the MD5 hash for letmein. A salt is intended to help prevent this sort of thing.
Let's suppose you have a function, randomStringGenerator() that generates a random $x-character string. To use it to salt a password, you'd do something like this:
$password = 'letmein';
$salt = randomStringGenerator(64); //let's pretend this is 747B517C80567D86906CD28443B992209B8EC601A74A2D18E5E80070703C5F49
$hash = md5($password . $salt);
You'd be then performing md5(letmein747B517C80567D86906CD28443B992209B8EC601A74A2D18E5E80070703C5F49), which returns af7cbbc1eacf780e70344af1a4b16698, which can't be "looked up" as easily as letmein without a salt.
You'd then store BOTH the hash and the salt, and when the user types in their password to log in, you'd repeat the process above and see if the password the user entered with the stored salt appended hashes to the same thing as the stored hash.
However! Since general hashing algorithms like MD5 and SHA2 are so fast, you shouldn't use them for storing passwords. Check out phpass for a PHP implementation of bcrypt.
Hope that helps!
One uses a salt to avoid the attacker creating a rainbow table, e.g. a table containing all (usual) passwords and the corresponding hashes, sorted (or somehow easily accessible) by hash. If the attacker has such a table or can create it, and then gets your password database with unsalted hashes, he can easily look up the passwords, even for all of your users at once.
If the hashes are salted (and the attacker gets the salt with the hashes), he will still be able to do the same attack (with only slightly more work to input the salt) - but now this work of building a rainbow table is useless for the next hash with another salt, which means this will need to be done for each user again. This alone is the goal of the salt. A dictionary attack on your single account still needs the same time as before, just the rainbow table is useless. (To do something against the dictionary attack, see below.)
How exactly the salt is used depends on the algorithm in use. Some hash algorithms (for example bcrypt, which is specially made for password hashing) have a special salt input parameter (or generate the salt themselves and include it in the output):
H = bcrypt(password, hardness) or H = bcrypt(salt, password, hardness)
(The first variant generates the salt itself, while the second takes it from the outside. Both include the hash and the hardness parameter in the output.)
Others need to be used in some special mode to use the salt.
A simple variant which works for most hash algorithms would be using HMAC, with the salt as "message" input, the password as key:
HMAC(password, salt) = Hash(password ⊕ opad || Hash(ipad ⊕ password || salt) )
where opad and ipad are some constant padding values.
Then you store the salt together with the hash. (For a slightly higher barrier, you could store the hash in another location than the salt. But you will still need both for login.) For login, you then will give the password and the stored salt to your hash function, and compare the result with the stored hash. (Most bcrypt libraries have a "password verification" function build in, which do this.)
For password storage it is important to use a slow hash algorithm, not a fast one, to avoid (or really: slow down) brute force or dictionary attacks on the passwords, as most people will have quite short passwords. bcrypt is an algorithm which was made just for this goal (its slowness is adaptable by a parameter).
If you use a fast hash function, be sure to repeat it often enough to be slow again. (But better, really: use bcrypt.)
Although #Chris and #Pualo have very good answers. I wanted to add one more thing about salting passwords that hasn't been expressed.
Salting a password is not a real protection mechanism. It doesn't matter if you are using bcrypt or any other mechanism. It is simply a delaying tactic, nothing more.
By using a different salt value per password you are forcing the hacker to create a rainbow table per password in order to crack them. This increases the amount of time it takes, but by no means does it make it impossible. Bear in mind that with cloud based computing you can spin up a large number of machines to create the rainbow tables and you can see that the delay is pretty small.
Further, most of the zombie machines out there are available for rent...
That said, the reason why you go through the trouble is to buy time. Time to notice that you've been breached, repair it and inform your users of the breach. That's it.
If an attacker obtained enough access to your database to pull the list of passwords, then it is pretty much guaranteed that they've obtained everything else. So, by this point you've already lost everything. The only question is how long does it take you to plug the hole, reset everyone's password and tell them that they should reset the passwords on any other account they may have where they used the same one. If you're Sony, then this time is apparently measured in months, if not years... ;) Try to be a little faster than that.
So, although it is the responsible thing to do it is only one part of your defensive tool belt. If you've been breached then you can bet those usernames and passwords will show up on a site somewhere at some point in the near future. Hopefully before then you've already cleaned up your house.
Using salt prevent precomputed rainbow-tables usage, as an example if a user use "Password" as a password, MD5("Password"), SHA1("Password"), or WhatEver("Password") may be well-known results stored in some rainbow tables.
If you use a different salt value per person - called a nonce - you'll get MD5(HMAC("Password","RandomSaltValue")), SHA1("Password","AnotherRandomSaltValue"), ... that mean two different hashed password values for the same initial password.
Now the question about storing these salts value...i think they can be stored into the database, the idea of salts are to prevent rainbow-style attack, not the database compromised issue.
Although bcrypt slows the process significantly down, it still would probably be feasible to attack your scheme if lots of computations can be made in parallel. I know it's unlikely and this would have to be a quite resourceful attacker indeed, but let's imagine the site you protect would contain photos and documents from Area 51 :) In that case, given enough parallelization, you could still be in trouble even if using bcrypt.
That's why I like the approach of scrypt - not only does it involve computational cost, but also it imposes memory constraints, specifically to introduce cost in terms of space and to make these kinds of parallel attacks infeasible. I can only recommend reading the paper that is linked on that site, it illustrates the concept really well.
Although, it seems that bcrypt and even more scrypt seem to get less attention in terms of cryptanalysis than PBKDF2outlined in RSA's PKCS#5. See this discussion for details.
I'd say first of all that security is very hard to do right, and that you really should rely on existing libraries to do as much as possible for you. For basic operations like password storage and validation that's definitely true.
EDIT: Removed erroneous info. I'll stick with the only good advice I had, which was not to roll your own.
What about Secure hash and salt for PHP passwords? It even has examples in PHP.
Wondering whether it matters if a salt is unique for a single given user each time the password is changed, or whether it's not a big deal to reuse the same salt each time.
I currently generate a new random string as the salt each time a given user updates the password. This way each time the user has a new password their is also a salt change. It's easy to do, so why not.
Well... here's why. I need to store the previous X passwords to ensure a password is not reused. In the old days (the last time I wrote code for this), I could just store previous MD5 hashes, and compare new ones to that list. Well, now that I am using salted hashes where the salt is unique each time, those comparisons are no longer possible as the previous salts are no longer known.
To make that system work, I have two choices: store a history of the salts in addition to the final hashes, or reuse the same salt for any one given user with each password update. Either of these would allow me to build values that could be compared to a history.
The latter is less work, but does it lose any strength? From a practical standpoint, I don't see that it does. Thought I'd get a second opinion here. Thanks.
To keep the question "answerable" -- would reusing the same salt for any one user have an acceptably minimal reduction of protection in order to maintain a searchable password history (to prevent pswd recycling)?
Reusing the same salt means that if a user is explicitly targeted by a hacker, they could produce a "password to hash" dictionary using "the user's salt" - so that even if the user changes their password, the hacker will still immediately know the new password without any extra work.
I'd use a different salt each time.
As for storing the MD5 hash plus salt - presumably you're already storing the salt + hash, in order to validate the user's current password. Why can't you just keep that exact same information for historical checks? That way you can use one piece of code to do the password checking, instead of separating out the current and historical paths. They're doing the same thing, so it makes sense for them to use the same code.
EDIT: To explain what I mean, consider a 4 character salt, prepended to the password... and for the sake of argument, imagine that someone only uses A-Z, a-z and 0-9 in their password (and the salt).
If you don't know the salt ahead of time (when preparing a dictionary attack) then in order to prepare a dictionary for all 8 character "human" passwords, you need to hash 62^12 concatenated passwords. If, however, you always know what the first 4 characters of the concatenated password will be (because you know the salt ahead of time) then you can get away with only hashing 62^8 values - all those beginning with the salt. It renders the salt useless against that particular attack.
This only works with a targeted user of course - and only if the attacker can get at the hash list both before and after the password change. It basically makes changing the password less effective as a security measure.
Another reason for using salt in password hashes is to hide the fact that two users use the same password (not unusual). With different hashes an attacker won't see that.
Firstly, stop using MD5 (if you are using it), and use SHA-2, MD5, SHA-0, and SHA-1, are all dead hashes.
-- Edit:
I now agree with Jon Skeet, and suggest you consider generating a new salt with each password change. It covers a small case where the attacker may get the salt+hash, then not be able to gain access again, but will still allow him (with some guessing of how you combine them), to calculate what the hashes could be for all future passwords. It's very small, and is not so important, because the password sizes will need to be significantly small (say, 8 chars) for even calculating them all offline to be practical. Yet it exists.
Secondly, to consider whether or not it matters, we need to think about the purpose of salts. It is to prevent offline attacks against someone who has a complete listing of only the passwords.
On this basis, if the salt is equally "difficult" to obtain before and after password changes, I see no use a new salt (it's just as at-risk as it was before). It adds additional complexity, and in implementing complexity is where most security problems occur.
I might be being incredibly dim here, but, where would you store the salt that would be inaccessable to someone with enough access to get the hashed password.
I am possibly taking over an app that literally just encrypts user passwords by doing md5( password )
They have ~2000 users to date. How can I migrate those passwords to a stronger encryption schema (e.g. involving a salt, user-specific hash, and their password, all encrypted with sha1, bcrypt, whatever)?
MD5 is a cryptographic hash function, not necessarily an encryption method. A hash is designed to only be performed in one direction, and cannot be reversed other than by dictionary attack. As an example, you can try out this hash database lookup if you're feeling frisky.
You will probably want to save these old passwords in a separate column, then when the users login to the "new" system, compare the MD5'ed version of that password with the old one, and if the digest matches, perform SHA1 with a salt on that password and store that in a separate column.
Alternatively, and probably a better approach, is the force the users to change passwords... and when they enter their new one, use the new hash algorithm on it instead.