Аутентификация пароля, зашифрованного в PHP, с использованием Blowfish с Ruby

Есть приложение, написанное на PHP, которое я конвертирую в Ruby. При шифровании паролей приложение PHP использует следующий код:

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

Я предполагаю, что это использует реализацию Blowfish. Здесь x — это все символы a-zA-Z0-9.

Реализация Blowfish на Ruby использует следующий синтаксис (взято с http://crypt.rubyforge.org/blowfish.html) :

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

У меня нет строки длиной 56 или меньше байт, и неясно, что это должно быть из версии PHP. Итак, как я могу написать функцию Ruby, которая будет шифровать пароли, чтобы получить тот же результат, что и PHP?


person Luke Saunders    schedule 16.12.2011    source источник


Ответы (1)


Код PHP хэширует $pass с солью $2a$07$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxx$, если установлено CRYPT_BLOWFISH (CRYPT_BLOWFISH == 1). Соль должна соответствовать формату, указанному в документации PHP ("$2a$", a two digit cost parameter, "$", and 22 digits from the alphabet "./0-9A-Za-z").

Я не уверен, что вы можете сделать это с библиотекой, на которую вы ссылаетесь, но вместо этого вы можете использовать bcrypt-ruby.

Для вашего кода это будет примерно так, я использую те же данные из примера PHP ( http://php.net/manual/en/function.crypt.php), я беру только 29 первых символов соли, потому что дальше PHP ее игнорирует:

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"

Это дает вам тот же результат, что и в примере с PHP. Если ваша соль слишком длинная, возьмите первые 29 символов ($2a$07$ плюс следующие 22 дополнительных символа).

Я проверил поведение PHP, если соль слишком длинная (всего более 29 символов), остальное игнорируется, если соль слишком короткая, она вернет 0. Например, в 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
?>
person Jorge Núñez    schedule 10.01.2012