2

I am new to storing passwords on databases and from what I read I have created a simple php script below

<?php
  $salt =  openssl_random_pseudo_bytes (16);
  $password = "test";
  $hash = hash ("sha512" , $salt . $password);

  echo $hash;
?>
  1. Am I doing this correctly?
  2. Should the salt be stored in databases as byte datatype?
  3. Should the final hash be stored at String datatype in database?
Arya
  • 8,473
  • 27
  • 105
  • 175
  • What Will happen if any one hacks the db ? they can easily decrypt the password with the salt – Vijayaragavendran Jul 21 '14 at 10:10
  • 1
    `sha512` cannot be undone. It is a one-way transformation @Vijayaragavendran the only way around it would be to generate a rainbow table for all strings starting with the `$salt`, which is why I prefer to suffix the `$salt` instead of prefixing it. – t3chguy Jul 21 '14 at 10:12
  • it can be stored in a config file with some peculiar file name (Hard to guess) – Vijayaragavendran Jul 21 '14 at 10:12
  • you can use the built in PHP function crypt - http://php.net/manual/en/function.crypt.php – Ciaran Jul 21 '14 at 10:13
  • Also see Openwall's [PHP password hashing framework](http://www.openwall.com/phpass/) (PHPass). Its portable and hardened against a number of common attacks on user passwords. The guy who wrote the framework (SolarDesigner) is the same guy who wrote [John The Ripper](http://www.openwall.com/john/) and sits as a judge in the [Password Hashing Competition](http://password-hashing.net/). So he knows a thing or two about attacks on passwords. – jww Oct 12 '14 at 00:51

3 Answers3

1

If you are running (PHP 5 >= 5.5.0) then you can take advantage of the built-in php password hashing functionality.

Simple usage:

$options = [
    'cost' => 11,
    'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM), // or your own salt here
];

$pass_hash = password_hash("helloworld", PASSWORD_BCRYPT, $options);

if (password_verify('helloworld', $pass_hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
Latheesan
  • 23,247
  • 32
  • 107
  • 201
1

The SHA* algorithms are not appropriate to hash passwords, because they are ways too fast, and therefore can be brute-forced too fast. Instead one should use a slow algorithm like BCrypt or PBKDF2 with a cost factor, which controls the necessary time.

PHP supports the BCrypt algorithm with the new function password_hash(). There also exists a compatibility pack for earlier PHP versions.

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

It is recommended that you do not pass your own salt, instead let the function create a cryptographically safe salt from the random source of the operating system.

The salt will be included in the resulting hash-value, so you don't have to store it separately. Just create a 60 character string field in your database and store the hash-value. The function password_verify() will extract the used salt from the stored hash-value. For more information you can have a look at my tutorial about storing passwords.

martinstoeckli
  • 23,430
  • 6
  • 56
  • 87
-2

normally I stored the salt with hashed password. I have my own format to recognize the salt form the hashed password. for example, the hashed password is 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824, and the salt is aaabbb. I append salt to hashed password like 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824aaabbb. So I can recognize the last 6 word is salt for this hashed password. Even the db has been hacked, they still didn't know the salt and the real password.

  • 1
    what if i tell you, if your db is hijacked in 90% percent your php code is leaked too – ins0 Jul 21 '14 at 10:40
  • Risk: SQL Injection + ` INTO OUTFILE` -> Filesystem compromise. (Unless your DB is on separate hardware than the webserver.) This is not a good design. – Scott Arciszewski Jul 21 '14 at 14:29