Authentication of PHP Encrypted Password Using Blowfish with Ruby

There is an application written in PHP that I convert to Ruby. When encrypting passwords, the PHP application uses the following code:

if($method == 2 && CRYPT_BLOWFISH) return crypt($pass, '$2a$07$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxx$'); 

I guess this uses the Blowfish implementation. Here x is all the characters a-zA-Z0-9.

The Ruby implementation of Blowfish uses the following syntax (taken from http://crypt.rubyforge.org/blowfish.html ):

 blowfish = Crypt::Blowfish.new("A key up to 56 bytes long") plainBlock = "ABCD1234" encryptedBlock = blowfish.encrypt_block(plainBlock) 

I don’t have a string 56 or less bytes long, and it’s not clear what should be from the PHP version. So, how can I write a Ruby function that will encrypt passwords to give the same result as PHP?

+6
source share
1 answer

The PHP code hashes $pass with the salt $2a$07$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxx$ if CRYPT_BLOWFISH set ( CRYPT_BLOWFISH == 1 ). The salt must match the format specified in the PHP documentation ( "$2a$", a two digit cost parameter, "$", and 22 digits from the alphabet "./0-9A-Za-z" ).

I'm not sure that you can do this with the library you are referring to, but you can use bcrypt-ruby instead.

For your code, it will be something like this, I use the same data from the PHP example ( http://php.net/manual/en/function.crypt.php ), I only accept the first 29 characters of salt, because PHP ignores this:

 require 'bcrypt-ruby' pass = "rasmuslerdorf" # Here you should put the $pass from your PHP code salt = '$2a$07$usesomesillystringfors' # Notice no $ at the end. Here goes your salt hashed_password = BCrypt::Engine.hash_secret(pass,salt) # => "$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi" 

This gives you the same result as the PHP example. If your salt is too long, take the first 29 characters ($ 2a $ 07 $ plus the next 22 extra characters).

I tested the behavior of PHP if the salt is too long (no more than 29 characters), the rest are ignored, if the salt is too short, it will return 0. For example, in PHP:

 <?php crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$') // returns $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi crypt('rasmuslerdorf', '$2a$07$usesomesillystringfors') // returns $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi crypt('rasmuslerdorf', '$2a$07$usesomesilly') // returns 0 because the salt is not long enough ?> 
+4
source

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


All Articles