PHP crypt with different results

Well, I’ve been sitting here since I scratch my head in this matter, and I can’t understand what’s wrong. I am trying to encrypt a password using random salt using crypt, but when I try to log in, it is always wrong.

Let me guide you through the script:

$cost = 10; $salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.'); $salt = sprintf("$2y$%02d$", $cost) . $salt; $hash = crypt($password, $salt); echo $hash; echo crypt($password, $hash); 

Outputs the following with a password as 'asdfgh':

 $2y$10$865uru.sXJheD9TQKLDnZuTZfpAXv83UDuaSFfb.G2qIxBzEb1pOi $2y$10$865uru.sXJheD9TQKLDnZuTZfpAXv83UDuaSFfb.G2qIxBzEb1pOi 

The hash in the database is as follows:

 $2y$10$865uru.sXJheD9TQKLDnZuTZfpAXv83UDuaSFfb.G2qIxBzEb1pOi 

To enter the script for testing, we have the following code:

 echo $data->hash . '<br>'; echo crypt('asdfgh', $data->hash) . '<br>'; echo crypt('asdfgh', '$2y$10$865uru.sXJheD9TQKLDnZuTZfpAXv83UDuaSFfb.G2qIxBzEb1pOi'); 

And this outputs the following:

 $2y$10$865uru.sXJheD9TQKLDnZuTZfpAXv83UDuaSFfb.G2qIxBzEb1pOi $2y$10$865uru.sXJheD9TQKLDnZuRRPJQwjWh2PGgtntpcsnRaGzvv5Sfte $2y$10$865uru.sXJheD9TQKLDnZuRRPJQwjWh2PGgtntpcsnRaGzvv5Sfte 

As long as the database row is still correct, and even by passing the correct row manually to the function, the generated hash is different. I have no solutions ...

If anyone could help me, I would really appreciate it.

PHP Version 5.4.16 for Windows

UPDATE: The following are updated salt fragments:

 $cost = 10; $salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.'); $salt = sprintf("$2y$%02d$", $cost) . $salt; $hash = crypt($password, $salt); $data = array( 'id' => '', 'username' => $username, 'hash' => $hash, 'email' => $email, 'salt' => $salt, ); $this->mdl_registration->_insert($data); $this->load->view('registration_submit'); 

To enter the script:

 function check_login($password) { $username = $this->input->post('username'); $result = $this->get_where_custom('username', $username); foreach($result->result() as $data) { echo $data->hash . '<br>'; echo crypt('asdfgh', $data->salt) . '<br>'; $test = crypt($password, $data->salt); if($test == $data->hash) { return TRUE; } else { $this->form_validation->set_message('check_login', 'Invalid Username and / or Password'); return FALSE; } } } 

An echo for testing purposes returns the following:

 $2y$10$ZgbOXM18lArDu/u/Ftsdr.t7VPnLsqLJdC2Dum8pl/flW8LmnnUoS $2y$10$ZgbOXM18lArDu/u/Ftsdr.s5N5juHB/zq/5SN/7oFAjn9CZKjI9H6 
+4
source share
2 answers

Well, my answer does not really decide why this code does not work. I thought this was due to the salt not passing, but apparently crypt() takes this into account while the salt is within the limits of the provided $hash ...

Anyway, I can offer an alternative method for this. Feel free to ignore this and wait for a solution or adapt it. To you.

 $password = 'asdfgh'; $salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647)); $hash = hash('sha256', $password . $salt); for($round = 0; $round < 60000; $round++) { $hash = hash('sha256', $hash . $salt); } 

This creates the salt a little differently, uses a different hash algorithm, and iterates through the hash 60,000 times (relatively short for the user 1-2 seconds).

Save this $ salt in the database with the $ hash.

Now, to log in to the script, simply enable this snippet ...

(assuming $ is asdfgh password)

 $newHash = hash('sha256', $password . $salt); for($round = 0; $round < 60000; $round++) { $newHash = hash('sha256', $newHash . $salt); } if($newHash===$data->hash){ //Match! } 

I tried this with several different datasets and the hashes always matched, so you can use this.

Or you can wait until a real security expert explains why your code doesn’t work :)

Hope this helps!

0
source

Your salt is in the wrong format.

According to docs :

CRYPT_BLOWFISH - hash of Blowfish with salt as follows: "$ 2a $", "$ 2x $" or "$ 2y $", two-digit value parameter, "$" and 22 characters from the alphabet "./0-9A-Za-Z" .

Your salt has a) invalid characters ( = as a padding character at the end of base64) and b) too long (24 characters instead of 22).

This may be the cause of your problem.

0
source

Source: https://habr.com/ru/post/1495378/


All Articles