-1

I am trying to hash the password using SHA256 with random salt and random key in php and storing back hash value with salt and key used. I want to know does this provide adequate safety?

The following is code:

function hashpwd($string, $salt, $KEY)
{
    if(strcmp($KEY, '')==0)
        $KEY=openssl_random_pseudo_bytes(32); //key used for encryption and decryption
    if(strcmp($salt, '')==0)
    {
        $salt= openssl_random_pseudo_bytes(32);
    }
    $string = $salt.$string;
    $pwd = hash_hmac("SHA256", $string, $KEY);
    //echo "$salt".$pwd."<br>";
    return base64_encode($salt).base64_encode($KEY).$pwd;
}

Should I use double salt?

Note: Running on PC not sure of affording multiple iterations of hashing.

EDIT:

I changed the code to following, used password_hash() with BCRYPT and 5000 rounds:

function hashpwd($password)
{
        $salt='';
        $strong = FALSE;
        while (!$strong){
            $salt = openssl_random_pseudo_bytes(32,$strong);
        }
        $pwd = rtrim(password_hash($password, PASSWORD_BCRYPT, array('rounds'=> 5000, 'salt'=> $salt)));
        return $pwd;
}

Is the above code good enough?

I am not questioning the security of BCRYPT, My question was to know which of the two codes was better to use.

1 Answers1

2

You can definitely use multiple iterations of hashes; I can use thousands to hundreds of thousands of iterations even on my smartphone!

For PHP in particular, look at the password_hash() and password_verify() functions, per the PHP.net Password Hashing FAQ. Use the PASSWORD_BCRYPT mode, and set the cost as high as your hardware can handle and still provide response times the user is willing to accept - you can usually use a reasonable fraction of a second, since good password hashing is single-threaded.

Please read Thomas Pornin's canonical answer to How to securely hash passwords? before you try any password hashing. To summarize:

  • Never use a single pass of any hashing algorithm.
  • Never roll your own, which is what your example 2 is (and example 1 as well, if + means concatenation).
  • Username stored in the clear
  • Salt generated per user, 8-16 random bytes, stored in the clear
    • in pure binary or encoded into Base64 or hex or whatever you like.
  • Use BCrypt, SCrypt, or PBKDF2
  • Use as high an work factor/cost/iteration count as your CPU's can handle during expected future peak times.
  • For PBKDF2 in particular, do not ask for more binary output bytes than the native hash produces. I would say not less than 20 binary bytes, regardless.
    • SHA-1: output = 20 bytes (40 hex digits)
    • SHA-224: 20 bytes <= output <= 28 bytes (56 hex digits)
    • SHA-256: 20 bytes <= output <= 32 bytes (64 hex digits)
    • SHA-384: 20 bytes <= output <= 48 bytes (96 hex digits)
    • SHA-512: 20 bytes <= output <= 64 bytes (128 hex digits)
  • For PBKDF2 in particular, SHA-384 and SHA-512 have a comparative advantage on 64-bit systems for the moment, as 2014 vintage GPU's many attackers will use have a smaller margin of advantage for 64-bit operations over your defensive CPU's than they would on 32-bit operations.
Anti-weakpasswords
  • 9,980
  • 2
  • 25
  • 53