There is an application written in PHP which I am converting to Ruby. When encrypting passwords the PHP app uses the following code:
if($method == 2 && CRYPT_BLOWFISH) return crypt($pass, '$2a$07$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxx$');
I'm assuming this is using a Blowfish implementation. The x's here are all a-zA-Z0-9 characters.
The Blowfish implementation in Ruby 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 56 or fewer byte long string and it's not clear what that should be from the PHP version. So how can I write a Ruby function which will encrypt passwords to give the same result as the PHP one?
The PHP code is hashing $pass
with the salt $2a$07$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxx$
if CRYPT_BLOWFISH
is set (CRYPT_BLOWFISH == 1
). The salt has to follow the format indicated in the PHP documentation ("$2a$", a two digit cost parameter, "$", and 22 digits from the alphabet "./0-9A-Za-z"
).
I'm not sure if you can do it with the library you are referring, but you can use bcrypt-ruby
instead.
For your code it would be something like this, I'm using the same data from the PHP example ( http://php.net/manual/en/function.crypt.php ), I only take the 29 first characters of the salt because beyond that PHP ignores it:
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 output as on 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 (beyond 29 characters in total) the rest is ignored, if the salt is too short it will return 0. E.g 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
?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With