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.
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.
This question already has answers here:
What is the advantage of salting a password hash?
(3 answers)
Closed 8 years ago.
When using salt in a password hash, why is it recommended to use a different salt for each password and store it unencrypted in the database?
It seems so pointless. Surely if an attacker gets access to the database and they find out the salt it's just like having no salt at all?
If they are trying to crack passwords through bruteforce and they have the plain unencrypted salt right there in the same row as the encrypted password, they could just concatenate the salt with all the words/phrases they are going to try couldn't they?
The point of the salt is to prevent someone from attacking all the passwords at once. Since each password has a different salt, an attacker has to attack them individually. This greatly reduces the number of possible passwords he can try for each account.
Otherwise, an attacker could just hash a billion possible passwords and then compare each hashed password against his list.
See http://en.wikipedia.org/wiki/Rainbow_table first.
If you use a random salt for each password, the hacker cannot make use of a rainbow table.
You need to store the salt unencrypted, to be able to hash a string to check if it matches the salted hash of the original password.
Some crypt functions concatenate the unencrypted salt (amongst other things) to the encrypted, salted password. Der php bcrypt blowfish for example.
To bruteforce a hashed password, an attacker needs to try to hash all possible combinations of letters and symbols and compare it to the hashes he has.
If the attacker has bruteforced a plaintext > hash combination like this once, he knows the plaintext for all identical hashes.
A salt is added to a plaintext before hashing so the same plaintext hashes to a different hash, forcing an attacker to try all combinations of letters for each individual hash, slowing him down tremendously.
A public salt makes it more time-consuming to crack a list of passwords. However, it does not make dictionary attacks harder when cracking a single password. The attacker has access to both the encrypted password and the salt, so when running the dictionary attack, the attacker can simply use the known salt when attempting to crack the password.
http://en.wikipedia.org/wiki/Salt_%28cryptography%29
If someone gets a hold of your DB, you're in big, big trouble for a variety of reasons. It would be a lot easier for an attacker to get (or guess) a single salt .. in theory. If they know the only salt you use, they can brute force all passwords simultaneously. If you use a different salt for each user, the attacker has to know each individual salt to attack effectively.
As for encrypting the salt for storage .. I suppose there's nothing wrong with doing that, it's just that it is hopefully rare that an attacker will be able to dump your entire DB. If they could, they may be able to get what they were after anyway even without having to circumvent authentication.
You need the salt to make rainbow tables and that sort of things useless.
The salt can be stored encrypted of course, making things a bit more complicated to crack a single password.
But look how it usually works: You send the salt to the client which uses it to hash the salt+password. So your client would have to decrypt the salt first, which can be done by any atacker in many cases. In cases where the attacker hasn't got the chance to observe the client-behaviour, encrypted hashes might improve security (security by obscurity).
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.
I'm trying to secure a website that is being moved to a public server soon. I've just finished adding the password hashing functions to all of my login scripts. I'm using FormsAuthentication.HashPasswordForStoringInConfigFile(pw, method) to do so. I have a question about the process I'm using and whether or not it's secure for a web server:
Password is sent in plain text over HTTPS to the server
The server looks in the Users table to find the user's Salt (several random characters) and their hashed and salted stored password
The plain text password is appended with the Salt
The new string is hashed using the above function
The newly hashed version is compared to the stored version
If equal, login is allowed
If not equal, the login attempt is logged in Session variables, up to 3 times before locking out the user's machine from accessing the login page until an admin verifies IP address and unlocks.
Does this look about right? I just don't see how the salt is effective in this method... Anyway, all I've done is add a salt and hash. Is this considered Encryption? Or am I missing a step? I remember reading that hashing algorithms like SHA1 and MD5 are not encyption algorithms, so what else needs to be done?
That is correct. The salt is used to prevent rainbow table attacks where a dictionary of common works hashed with MD5 is used to try to gain entry. Using the salt ensures that even if they had an MD5 hash of the word, it wouldn't work because they don't know the salt.
The MD5 algorithm is a 1 way hash algorithm, and not an encryption value. The difference is, once you've hashed the value, there is no way to get back to the original value. Encryption allows you to decrypt the data and get back the original value. So you are correct, they are not the same, and your passwords are not encrypted, they are hashed. This means that if someone forgets their password, you cannot send it to them. You have to provide a way for them to reset their password instead. This also means that anyone with access to the database would not have access to raw passwords. Which is good because a lot of people use the same password everywhere, and if you had access to a large list of usernames and passwords, someone could decide to start trying to log into bank / credit card websites.
What you are doing is a recommended practice.
You shouldn't be storing the retry count in the session - an attacker could simply discard their session cookie after each attempt, allowing them to retry as many times as they wish. Instead, store it against the user record.
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.