Вопрос

This is my first time using the crypt() function in PHP, and I can't figure out why it isn't working. My code is based on this article: http://www.techrepublic.com/blog/australia/securing-passwords-with-blowfish/1274

function blowfishHash ($pw) {
   //generate random salt
   $salt = "$2y$10$";
   for ($i = 0; $i < 22; $i++) {
       $salt .= substr("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", mt_rand(0, 63), 1);
   }
  $hash = crypt($pw, $salt);

  //printout to file
  $file = fopen("debug.txt", "w+");
  fwrite($file, "\n\n\n".$pw);
  fwrite($file, "\n\n\n".$salt);
  fwrite($file, "\n\n\n".$hash);
  fclose($file);

  return $hash;
}

I called the function with the sample password "password".

The resultant salt was: $2y$10$NzRQNjTRfP4jXKvb4TCO.G
But the password was "$2mV0NZp92R3g" – which seems far too short.

Could someone please help me figure out what I'm doing wrong?

Это было полезно?

Решение

As you stated in your comment, you are using PHP 5.2.x.

The Blowfish implementation is only available in PHP >= 5.3.x. If for any reason it is not possible to install a newer PHP version, you could check here on more information on how to make Blowfish work with older PHP versions.

Другие советы

Since crypt in PHP 5.2 doesn't support CRYPT_BLOWFISH, it is instead defaulting to interpreting the salt as a CRYPT_DES style salt. Notice that the output starts with "$2", which is the two character salt that CRYPT_DES chose from the salt input and prepended to the hash, and the output length matches the exact CRYPT_DES output length.

Interestingly, you can achieve the same result in later PHP versions with CRYPT_BLOWFISH support by simply truncating the salt to two characters. Ie:

crypt('password', '$2y$10$NzRQNjTRfP4jXKvb4TCO.G')   /* in PHP 5.2 */ 
 ==
crypt('password', '$2')   /* in PHP 5.4 */

In theory, this might come in handy for backwards-compatibility if a CRYPT_BLOWFISH style salt was used in error on PHP 5.2.

This actually caused me a bit of confusion recently because the "$" character isn't valid salt input for CRYPT_DES as per the PHP crypt documentation, which says:

Standard DES-based hash with a two character salt from the alphabet "./0-9A-Za-z". Using invalid characters in the salt will cause crypt() to fail.

But here the "$" character clearly seems to be accepted by crypt() in both v5.2 and v5.4.

It would be both clearer and safer if crypt actually returned a failure like the documentation says it's supposed to, rather than accepting the "$" and defaulting to CRYPT_DES.

here is my blowfish encryption function ....

<?php
    function bcrypt($input, $salt=null, $rounds=12) {
        if($rounds < 4 || $rounds > 31) $rounds = 12;
        if(is_null($salt)) $salt = sprintf('$2a$%02d$', $rounds).substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 22);
        return crypt($input, $salt);
    }
    $hash = bcrypt('password');
    if($hash = bcrypt('password', $hash)) {
        // password ok
    }

?>

Initially only blowfish hashing with a salt starting with $2a$ was supported.

$2x$ and $2y$ Blowfish modes were added in PHP 5.3.7 to deal with potential high-bit attacks.

Your PHP 5.2.17 does not support $2y$ Blowfish mode.

This why your code is not working.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top