EasyBB
EasyBB

Reputation: 6564

PHP Class Function for hashing

public function kryptonite($string){
   $salt = "";
   $salt_vars = array_merge(range("A","Z"),range("a","z"),range(0,9));
   for($i=0;$i < 22;$i++){
        $salt.= $salt_vars[array_rand($salt_vars)];
   }
   return crypt($string, '$6$'.$salt);
  }

This returns on refresh:

$6$vnuqcEA70$CHWmPVsDVb.lVpq1PNsDn7.0fSmBX6FU2PlofK6dJOH7FQp6EdSsde3Aw6to8fY1L01/WOcWz8OIE0OxK1LTj.
$6$7lmp9sD4g$I0fAcDjno2Lf255gg6TxTLt9TRwR803ZXiU9BOWJXhWrGbJdPJ3LvAW9w2KbRZ/3EDSSbFrgF7rV7DdB0VliA0

If you closely at the first few lines it's changing constantly. I don't think Hashing is suppose to constantly change! So technically I'll never be able to test against this. Can someone help me with my kryptonite crypt function or explain to me what went wrong really.

Upvotes: 0

Views: 320

Answers (3)

Sam Dufel
Sam Dufel

Reputation: 17598

As a matter of fact, hashing is supposed to randomly change - it's called random salting. Your crypt function is creating a random salt which is fed to the SHA-512 hasher.

The output of crypt() includes the salt value, which you would then use when hashing a password to compare it to the stored hash.

public function kryptonite($string, $salt = null){
    if ($salt === null) {
        $salt = "";
        $salt_vars = array_merge(range("A","Z"),range("a","z"),range(0,9));
        for($i=0;$i < 22;$i++){
            $salt.= $salt_vars[array_rand($salt_vars)];
        }
        $salt = '$6$' . $salt;
    }
    return crypt($string, $salt);
}

To use this, you'd just do the following:

$storedHash = '.....'; // fetched from database
$inputPassword = '.....'; // from the user

$salt = preg_match('/\$[0-9]\$(.+)\$/')[1]; // php 5.4+

if (kryptonite($inputPassword, $salt) == $storedHash) {
    //.... success
}

Note that the array_random implementation of creating a random salt isn't cryptographically secure - it'd be better to use openssl_random_pseudo_bytes() or mt_rand() or such.

Upvotes: 2

Curtis Crewe
Curtis Crewe

Reputation: 4336

You won't be able to get the same result when using array_rand() I'd recommend something like this if you're going to use salts and need a two way encryption

function parse($action, $string) {
    $output = false;
    $encrypt_method = "AES-256-CBC";

    // hash
    $key = hash('sha256', "random encryption key that must stay the same");

    // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
    $iv = substr(hash('sha256', "ARANDOMIV"), 0, 16);

    if($action == 'encrypt') {
        $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
        $output = base64_encode($output);
    } else if( $action == 'decrypt' ){
        $output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
    }
    return $output;
}

Upvotes: 1

alex
alex

Reputation: 490413

You won't get the same hashes when you're using the array_rand() function. The result needs to be deterministic.

Is there a reason why sha1() isn't good enough?

Upvotes: 0

Related Questions