How does a website know what salt to use when you try to login - hash

For example let's say my password is "foo" and the website is using a md5 hash on passwords with a unique salt appended to it.
So when I register my password will be stored as "foo" with a salt appended to it and then md5 hashed.
Then when I send a login request the website will append a salt to "foo" and then md5 hash it, but how will the website know what the correct unique salt to use is?
How will the website magically know the correct unique salt to append to my password which is then md5 hashed, to verify the password I entered is equal to the md5 hashed salted password in the database?

This is the usual process of handling passwords:
User registers with a password.
A new data record is created for their user ID (which can come in the form of username or email, etc.)
Their password is handled:
A salt is generated for them, and that salt is saved in the data record. It's very common and recommended that the salt is visible right next to the password hash.
The password is combined with the salt (typically a library handles even this step for you, as any little nuance like appending salt matters a lot in security).
The password is hashed using a function designed for password hashing. This is usually quite computationally expensive to frustrate brute force attempts.
The password hash is stored in the data record, and the original password is discarded.
Then when they log in, there's no magic here:
The data record is looked up using their user ID.
The password they give is combined with the salt from the data record and then hashed.
If it matches the hash stored, they are granted access.
Some notes:
Password hashing is expensive. I don't think it's uncommon for it to take more than 1 whole second of computing time. Imagine the processing load if a thousand people are logging in at once.
A lot of things can go wrong if you aren't using a decent library to handle password hashing. Writing any of the steps yourself is not recommended.
It's common for libraries to output a coded string that contains everything you need to verify against a password, such as a version code, the hash, and the salt used.

Related

How exactly does a bcrypt hash prevent rainbow table lookup?

I'm very close to understanding exactly how the compare function of bcrypt works, but there are a few missing holes in my knowledge.
My understanding so far:
brcypt gens a hashed password using a plain text password and a randomly generated salt. The hashed password is a combination of the bcrypt version, the hashed salt and the concatenated hashed plain text password. When a user logs in, their plain text password is ran through the compare function. At that point, bcrypt knows how many characters in the hash and from what offset to begin to slice the hashed salt out of the full hash. It then concatenates the salt with the passed in plain text password, running it through the hashing algorithm to arrive at the final hashed string. The hashed string is compared to the hashed string in the database and if there is an exact character match, the password is correct.
2 questions..
Aren't hashes supposed to be impossible to reverse? If so, then how does bcrypt know how to decrypt the hashed salt and then use it to hash the incoming plain text password. That doesn't make any logical sense to me.
If brcypts algorithm is written such that it can always create a hashed salt that it always knows how to decrypt, can't hackers just use that algorithm to grab every hashed password from a database and slice the salts out? Then it could create a rainbow table for every salt and crack each individual password? That seems logical to me.
Pardon if my question doesn't make any sense. Happy to edit.
Read articles, read stack overflow questions, watched videos and asked a senior engineer.
A rainbow table is a pre-compiled list of every password you can find, and their hash.
Your rainbow table has:
hash("password1234")
hash("hunter2")
hash("correct horse battery staple")
But it doesn't have:
hash("ȃ#🙍♽😔ƅ😠☸☑+password1234")
hash("ȃ#🙍♽😔ƅ😠☸☑+hunter2")
hash("ȃ#🙍♽😔ƅ😠☸☑+correct horse battery staple")
You could go ahead and create a rainbow table that contains every password for this salt. But that's just called a Brute Force attack.
And this second rainbow table doesn't help you with the next website that chooses a different salt:
hash("®óó»♠☘☛🙈Ũh+password1234")
hash("®óó»♠☘☛🙈Ũh+hunter2")
hash("®óó»♠☘☛🙈Ũh+correct horse battery staple")
And to eliminate all the guesswork, and all the difficulty of storing a salt, and deciding a salt: modern password hashing algorithms generate a different random salt for every password for you, and store the salt in the resulting hash string for you:
hash("ȼŚ😑¥dĥ😥®µ+password1234")
hash("ČɆǝ%ËȌÁpmLȫ+hunter2")
hash("♼♄ș♰;⚁f)²ŋì😱³UÍ+correct horse battery staple")
Which is in essence what bcrypt does; it generates a different salt for every password.

when to hash a passwrd?

In my program I get the password into a variable (eg:string) and then before storing it into the database I hash it.Is that the correct and secured method?
Or should I hash it before storing it into a variable i.e. as soon as the user type in the password should it be hashed?
#Erina
Think about the purpose of hashing.
If someone breaks into your database they will not find passwords but only hashes which need to be brute forced into passwords in order to be useful.
By allowing the client to send a hash instead of the password you effectively make the hash the new password and all benefits are lost. i.e. if someone gets into the database they can instantly log into all accounts with the data they find there.
Therefore the client should always send the password and the server should do
the hashing.

Legacy app with md5 hashes: how to add salt and SHA1?

I've a legacy app where passwords are hashed using MD5 without salt. I'd like to switch to SHA1 with salt, but I'd like to keep current users' passwords.
My plan is to change hashing function to sha1(md5(password) + salt). I'll be able to batch process all existing hashes using sha1(<existing_pass> + salt).
Is it safe to keep md5 in this case?
Is it ok to have one single salt for all users?
It's not a good idea to keep md5, read this question: Use SHA-512 and salt to hash an MD5 hashed password?.
It's better to have one salt for each user. With the same salt, users with the same password will have the same hash, and a rainbow table can be created for all your passwords at the same time.
As for question 1 I'm not quite sure but it seems to be OK.
For question 2: It is never OK to have same salt for all users. Salt has two functions. To prevent using pre-generated hashes / rainbow tables to search leaked database, and to prevent generation of dictionary-based hashes and searching databases with them too. Common salt will work in first case making rainbow tables unusable, but won't prevent cracker from dictionary attack. If cracker knows the global salt, he can generate frequent passwords, hash them and grep entire database. If salt is generated per user this scenario isn't possible.

Can someone explain how salts help when storing hashed passwords?

I am having difficulty understanding how a salt which is appended to a hash helps improve the security when a database of passwords or other important information is compromised.
If the salt is, for example, "hello", and is appended to the password "password" then the salt and password are stored together, "hellopassword" and hashed to produce:
94e66f94517d606d5ad6d9191b980408952f2ed2 (sha1)
with the salt then appended:
hello$94e66f94517d606d5ad6d9191b980408952f2ed2
How is this more secure? The attacker knows the salt so can now compute the passwords with little extra difficulty... right? Or am I fundamentally misunderstanding something?
No, not with "little extra difficulty" - with potentially significantly more difficulty.
Imagine there are two billion common passwords. It's easy to hash all of those and store the results. Then if you have an unsalted password hash, you can just check which common passwords match the given hash.
Now compare that with a salted hash... now you have two billion common passwords, but also several billion possible salts. Computing all the possible salt/password combinations will take much, much longer - hopefully becoming infeasible.
Additionally, it means that even if two people have the same password, they are very likely to have different hashes - so carelessness of one user in revealing their password doesn't risk the security of the other.
See the Wikipedia entry (if you haven't already) for more on this.
salt helps in 2 ways:
1) When two (or more) people use the same password, without salt you can see who uses the same password (the hashes are all the same). So in theory, if that person knows one of those person's passwords he knows everyone's passwords with the same hash. This is a minor reason.
2) The main reason is to prevent attacks commonly called dictionary attacks or rainbow attacks. In these attacks someone uses a database of pre-calculated hashes for common passwords. Often times these databases are gigs in size. But it is very easy at that point to just do a lookup for the hashes you have (the hashed password) against the list of pre-calculated hashes and see what the associated password is.
By using a salt value (typically you want this to be a random number) the hash won't match the dictionary (the chance of them pre-calculating all passwords with all possible salt values is exponentially more difficult). So even if your user uses an easily attacked password, say "Password", which is pretty much guaranteed to be any in any password dictionary/rainbow table, by pre-pending your random salt value you make the hash pretty much guaranteed to be useless to the attacker. Meanwhile for you, since the salt is just stored in cleartext, it makes it very easy for you to add it to your cleartext for your comparison of the password the user entered.
The salt isn't appended to the hash, its appended to the password THEN hashed. This is more secure because hackers have to know the salt and the actual password, which you should both protect heavily. :D

What is the purpose of the "salt" when hashing?

Ok, I’m trying to understand the reason to use salt.
When a user registers I generate a unique salt for him/her that I store in DB. Then I hash it and the password with SHA1. And when he/she is logging in I re-hash it with sha1($salt.$password).
But if someone hacks my database he can see the hashed password AND the salt.
Is that harder to crack than just hashing the password with out salt? I don’t understand …
Sorry if I’m stupid …
If you don't use a salt then an attacker can precompute a password<->hash database offline even before they've broken into your server. Adding a salt massively increases the size of that database, making it harder to perform such an attack.
Also, once they've broken in they can guess a commonly used password, hash it, and then check all of the passwords in the database for a match. With a different salt for each user, they can only attack one password at a time.
There's an article at Wikipedia about salts in cryptography.
Another intention behind the use of a salt is to make sure two users with the same password won't end up having the same hash in the users table (assuming their salt are not the same). However, the combination of a salt and a password may lead to the same "string" or hash in the end and the hash will be exactly the same, so make sure to use a combination of salt and password where two different combination won't lead to the same hash.
If an attacker creates a giant table of hash values for plaintext passwords, using a salt prevents him from using the same table to crack more than one password. The attacker would have to generate a separate table for each salt. Note that for this to actually work propertly, your salt should be rather long. Otherwise the attacker's precomputed table is likely to contain the salt+password hash anyway.