3

Forgive me guys, I am completely new to password security and encrypting...

I am having problems comparing stored passwords that have been encrypted using php's crypt() function (using the blowfish hasing method) to a user's input. One way I have found I can compare the passwords is to store the salt used during encryption, to then encrypt the users input and compare this to the stored password.

Is this a secure way of doing things? Or is there a better (more secure) way of doing it?

Thanks.

  • I think the point is that it is one way encryption, and the way you are comparing is the only way to do it. – AlexP Jun 10 '13 at 23:33

3 Answers3

3

PHP's functions to generate a hash, will include the salt in the resulting hash-value. So if you store this hash-value, you already stored the salt. The verifying function can just extract this salt and use it again for verification. This method is safe, the salt is not meant to be secret.

Version 5.5 of PHP will have built-in support for BCrypt, the functions password_hash() and password_verify(). Actually these are just wrappers around the function crypt(), and shall make it easier to use it correctly. It takes care of the generation of a safe random salt, and provides good default values. For PHP version 5.3.7 and later, there exists a compatibility pack.

The easiest way to use this functions will be:

$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
martinstoeckli
  • 23,430
  • 6
  • 56
  • 87
2

Using a unique salt per user is a very good idea.

Storing the unique salt used for the particular user, along with the user's hashed password is a very acceptable approach that probably not used nearly as widely as it should be.

To confuse anyone who may get direct access to the user table of your database, consider storing both the salt and the hash in the same field of your database. Use a character that won't be a part of your salt or your hash, such as a colon (:) to separate them. This makes it easier to tease them apart programmatically at runtime.

STLDev
  • 5,950
  • 25
  • 36
  • @ranisalt - Thanks. Several times I've had to implement my own security provider and found this to be a useful technique. – STLDev Jun 10 '13 at 23:48
  • 1
    Just to add on to the blind alley idea. You can use anything that is already stored in the db as a salt. If you have 10 pieces of information why not pick one of them as the salt? To even further complicate things you could pick one piece of information as the salt based on another. For example, users with last name A-L use the date account was created as a salt but users M-Z use date of birth as a salt. Simple idea but you get the picture. – Phillip Berger Jun 11 '13 at 00:55
  • @Phillip - I've learned that it's best to use a somewhat long, random salt, calculated on a per-user basis. My salts are typically as long as the hash. – STLDev Jun 11 '13 at 01:40
  • I usually have salts of 32 characters long, using something random, timestamp and user email with md5, and I feel pretty safe. You could also use 2 md5 hashes (20 characters of each) which makes a safe and very random 40-character salt. – ranieri Jun 15 '13 at 20:42
  • @STLDeveloper, I really don't understand the need of put the salt in the middle of the hashed password, because, like martinstoeckli says, the salt is already in the beginning of the password stored. Another thing is that I think this would create a multivalued register, what would be in disagreement with some DB "rule". – Rafael Barros Sep 09 '13 at 16:26
  • @RafaelBarros, I'm not sure I follow. I'm not suggesting putting the salt in the middle of the hash, but merely pre-pending or appending it to the hashed password for storage of both into a single field. Please be aware that my comment is of a more generic nature and not specific to PHP. If, in fact, PHP's password hashing functions generate random salts and return these buried in the password hashes returned, and it seems they do, then I think that is an excellent approach and, of course, there would be no need to store any specifically calculated salt with the hash, as it's already there. – STLDev Sep 10 '13 at 04:46
1

Have a look at this article: https://sheriframadan.com/2013/05/password-hashing/

It contains what is currently considered to be the best practice for password encryption. It involves using blowfish encryption with a unique salt for each key. No need to try to store a hash and salt as parseable strings because the salt and the has are all one string that can be passed in as is for comparison operations.

adear11
  • 935
  • 6
  • 11