Reputation: 6564
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
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
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