1

Possible Duplicate:
Best way to prevent SQL Injection in PHP
The necessity of hiding the salt for a hash

I'm very new to MySQL and PHP, and have started self-learning it over the past couple of days and today I was looking at encryption for passwords etc. I've been looking through many webpages with information on the topic and most of them are saying to generate a random salt for every entry in the table (which I understand, you don't want the same salt for every entry) and this salt should then be stored in the table alongside the entry.

From what I've understood (correct me if I'm wrong), the encryption of the password doesn't prevent hackers from accessing it, rather just masks the true value if they do get access to the database. Surely if this is the case, you wouldn't want to store the salt in the table too - if the hacker has accessed the database and can see the encrypted data, showing him the salt just makes his job of decrypting infinitely easier?

Community
  • 1
  • 1
crazyloonybin
  • 935
  • 3
  • 18
  • 36
  • frankly if they have access to the db - game over. and unless your running a bank - you don't need to go crazy on security –  Jul 29 '12 at 20:43
  • If you are using bcrypt hashing method it is not necessary to store the salt in a database. You only need to store the hashed password. The salt is included in the hashed password. You only need to hash the new password with the old hash to verify if it is true. Have a look at the `crypt()`method: http://php.net/manual/en/function.crypt.php – Ukjent Jul 29 '12 at 20:45
  • 1
    @Dagon it might be game over for your site but you still have a responsibility (or at least you should have) to protect your users passwords because they may be using those for other services. – Vatev Jul 29 '12 at 20:48
  • OT: is that not the users responsibility to practice safe password usage (one per site) not mine? –  Jul 29 '12 at 20:49
  • @Dagon I agree accessing the database is game over but as Vatev said protecting it as much as possible is a must. – crazyloonybin Jul 29 '12 at 20:51
  • then encrypt everything as well as hashing for password. how far do you want to go. –  Jul 29 '12 at 20:52
  • @Ukjent I have implemented `crypt()` currently, and am using the salt as a fixed set of characters with the username appended onto the end multiple times in various orders, which means the salt can be recreated when the username is entered. – crazyloonybin Jul 29 '12 at 20:53
  • @Dagon users should have separate passwords for each of their accounts online, but in reality how often does that happen?! – crazyloonybin Jul 29 '12 at 20:58
  • @Dagon it is your responsibility to protect your users data as well as possible. – Vatev Jul 29 '12 at 20:58
  • my "responsibility" is limited to my sites terms of service and local law. Also known as "Trust no one" –  Jul 29 '12 at 21:00
  • @Dagon in that case please (for everyone's sake) don't give advice to others regarding privacy and security – Vatev Jul 29 '12 at 21:04
  • @Vatev if this was not the summer of love, I would tell you what you could do with your advice. –  Jul 29 '12 at 21:06

4 Answers4

4

The salt isn't used to encrypt. Instead, it goes (together with the password) into a hash function. That way, nobody (not even your application) can determine the password, but you can verify a password.

The salt is then used to require the attacker to attack each password hash individually (if the attacker wants just one password, the salt doesn't help in any way). Thanks to rainbow tables, it is fairly easy to compute the outputs of the hash function for common passwords.

The salt value is not secret, and can be safely stored in a MySQL database (or even published).

phihag
  • 278,196
  • 72
  • 453
  • 469
  • Thanks, makes a lot more sense having read that but confused as to what the difference between hashing and encrypting actually is? – crazyloonybin Jul 29 '12 at 21:00
  • encryption has a decryption algorithm that undoes its work if you know the secret key. Hashing is supposed to be one-way only. Once you do a hash you can't go back but it will always give the same value when you put the same value in. What you want to do here is hash the password with a salt appended, store that seemingly random value then when checking if the user typed the right password, hash that password with the same previous salt and compare the hashes. If an attacker gets the hash it is very hard to make it go the other direction to get the plaintext. – hackartist Jul 29 '12 at 21:07
  • @hackartist So hashing is better than encrypting as it only goes one way then? – crazyloonybin Jul 29 '12 at 21:11
  • I wouldn't necessarily say better but simpler and probably more secure for you. If you encrypt, then key to decrypt must be somewhere in your code or in a file on your server. If an attacker got in then your data is toast. If you hash, even you can't tell what the passwords were, but you can still verify if they were correct. The other thing is that the hash will always be the same size but the encryption might leak info about how long the password is depending on encryption method. Using a hash in this way is pretty standard for the web and for passwords. – hackartist Jul 29 '12 at 21:14
  • In terms of masking the data then, hashing is sufficient? (I decided to go for SHA-512). Then it's just securing the database which is a whole new ball park... *sigh* – crazyloonybin Jul 29 '12 at 21:21
  • @Crazyloonybin hashing is best practice. Any form of encryption is (normally) useless, as it doesn't hinder an attacker who has gained control over your application in any way. – phihag Jul 29 '12 at 21:23
2

The purpose of the salt is to prevent the use of Rainbow tables.These would allow a hacker to have generated a large number of pre generated hashes for certain passwords. By appending the salt to the password before it is hashed the hash is completely different than the original password.

password => 5f4dcc3b5aa765d61d8327deb882cf99
password+saltvalue => 1d7dc54c316b11f3a38cc24fa68e2b6a

thus they would need to recreate the hash for each salt value which is unpractical.

secretformula
  • 6,414
  • 3
  • 33
  • 56
2

It is perfectly fine to store the salt in the way that you are planning to. In fact it is fine to allow the attacker to see the salts. The purpose of the salt is to prevent people from being able to use prebuilt look up tables called rainbow tables by extending the size of the message space. All the salt does is make them throw out any precomputation and solve the whole problem which is time consuming but certainly possible (especially for hashes like md5 -- you should move to sha256)

You want to use different salts for each user so that an attacker would have to do the full amount of work for each password they recover rather than just generate a new table based on a single salt.

hackartist
  • 5,172
  • 4
  • 33
  • 48
-1

You can consider salt as something 'semi unique', it really does not have to be additional column called salt. Username, user email is also a kind of salt. So they are actually stored in db, next to hashed password. One problem with this approach occur when user decide to change a username or email.

mrok
  • 2,680
  • 3
  • 27
  • 46
  • Username and email should *not* be considered a valid salt, because they are not at all random. A salt value must be a random value to really be of use. – Andrew Barber Jul 30 '12 at 13:24
  • @Andrew who told you that? There is no difference between email and salt as a random string/int in separate column if attacker has your db? Salt should protect against rainbow tables (you cannot simple revert hash) and cracking password by brute force (too many unknowns factor). Please read first answer (by @phihag) in this question - he explained it in details. Let's make some test - this is my username "mrok" and this is my md5 password hash "954ad36392492cbdfc416445a35c17d8" (skip ")- please find my plain text password - salt is not random. – mrok Jul 30 '12 at 19:02