Migrating password encryption schemas - authentication

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.

Related

What's the point of encryption if there exists decryption?

Let's say in database user password is encrypting in MD5 and it's no more readable by human, but i can copy MD5 hash and go to any website which provide MD5 decryption and get actually password. So am I missing something?
MD5 is a one-way operation (hashing), it is not possible to decrypt it. But you can hash a lot of passwords and check whether the hashes are the same (brute-forcing). When you find a match, you can not know if that was the original password though, because many other passwords result in the same hash (collisions).
Mitigating brute-forcing and other cracking techniques is the goal of password-hash functions like BCrypt, SCrypt, PBKDF2 or Argon2. Absolutely use them instead of MD5 and you will see, that there exists no websites offering "decryption".

Convert passwords with sha256 to sha256 + salt

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.

Storing unencrypted salt for password hash in database [duplicate]

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).

Salted password hashes

I am trying to create a login system for a web application, but I am stuck on a couple of points. I am storing the password in my database using a sha2-512 hash with a 128 bit random salt.
However I currently have the password posted in plain text to my application using a html form, both when the account is created and when the user logs in. I know this is wrong.
Do I need to hash the password in the client? If so how do I take into account the salt which is currently generated and stored on the database?
NOTE: I am doing this to learn not to use in a production system
The best bet is generally just to use SSL. If you did need to hash on the client side, this is how I'd do it:
When you first store the password, hash the password with a stored salt as is commonly done.
When someone needs to login, send them the stored salt, along with a second, randomly generated salt.
The client will hash the plaintext password with the stored salt, then the random salt and send the hash to the server.
The server will hash the stored password with the random used in that request salt and compare.
This is secure because it ensures that the hash being transmitted is unique to the request (it uses a single-request random salt), so a login cannot be faked in the future simply by sending the hash again. It is not dangerous to send the client their stored salt, as it is assumed that password crackers will have access to the stored salt (if they get access to the db). Two hashes are required to prevent you from ever having to store the password as plaintext.
You should be using SSL to transmit the passwords encrypted so that a man-in-the-middle can't intercept the packets and read off what ever credential is being sent. Even if you pre-hash the password in the client, a man-in-the-middle can still just use that value to fake identity.
What really concerns me, though, is the use of SHA-512. A lot of people use cryptographic hashes for password storage, but popular opinion misses a very important point: These hashes were designed to be fast. That is, one of the requirements to become an SHA (or similar) hash is to be able to quickly hash large documents on embedded hardware.
This is the exact opposite of what you want for password storage, as it allows specialized routines on high performance GPUs to brute force passwords at a surprising and scary speed!
This is why some purpose built password storage hashes have been developed. The one I have been using is Bcrypt, which is slow enough to keep out brute force attacks, adjustable to couneract faster hardware in the future, and has the added bonus of handling the salting for you.
Hashing the password on the client would require the use of the salt on the client. This also exposes your algorithm for very easy hacking on the client side. The best thing to do is to perform this action over SSL (HTTPS) so that the entire transaction is encrypted and the authentication only happens on the server.
I.e.: Your user ID and password are transmitted encrypted from the client. The web server decrypts the data and passes it to your server-side authentication function where you look up the user and associated salt, perform password + salt + hash and compare it to the stored hash for a match. This means that the hash and then salt never need to be transmitted from the server at all.
You really need to be using SSL on any page where you are transmitting passwords. If you try to encrypt them on the client side it will be in javascript and very easily reverse-engineerable.

VB.Net Password Hashing practices

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.