Могу ли я воспроизвести точное поведение PHP-шифрования AES в ruby? - PullRequest
4 голосов
/ 15 июля 2011

Я нахожусь в процессе перестройки веб-приложения PHP в Ruby on Rails и очень хотел бы не заставлять всех существующих пользователей сбрасывать свои зашифрованные пароли. Сайт PHP использует mcrypt_encrypt с AES-256-ECB, и я не могу получить тот же зашифрованный текст, используя OpenSSL в Ruby. Я также не могу расшифровать их (что в принципе хорошо), поскольку то, что на самом деле хранится в пользовательской БД, представляет собой хэш MD5 текста AES-шифра.

Я прочитал эти предыдущие, тесно связанные вопросы и очень полезные ответы:

включая страницы, на которые есть ссылки, и, если я правильно понимаю, реализации PHP и ruby ​​используют разные методы заполнения. Поскольку мне приходится мириться с тем, как все работает на стороне PHP, есть ли какой-нибудь способ принудительно использовать один и тот же метод заполнения в ruby ​​/ OpenSSL? Я использую ruby ​​1.9.2-p180.

Вот пример кода на PHP:

$salt = "12345678901234567890123456789012";
$plain = "password";
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $plain, MCRYPT_MODE_ECB, $iv);

echo md5($cipher);

Вывод: 6337137fd88148250fd135a43dbeb84a

и в рубине:

require 'openssl'

salt = "12345678901234567890123456789012"
plain = "password";

c = OpenSSL::Cipher.new("AES-256-ECB")
c.encrypt
c.key = salt
cipher = c.update(plain)
cipher << c.final

puts Digest::MD5.hexdigest(cipher)

Вывод: 18dee36145c07ab83452aefe2590c391

Ответы [ 3 ]

5 голосов
/ 15 июля 2011

На самом деле это вообще не решение openssl, но, может быть, у вас есть рабочий пример.

require 'mcrypt'
require 'openssl'

plaintext = 'password'
puts plaintext

key = '12345678901234567890123456789012'

enc = Mcrypt.new(:rijndael_256, :ecb, key, nil, :zeros)
encrypted = enc.encrypt(plaintext)

puts Digest::MD5.hexdigest(encrypted)

Я использовал дополнительный драгоценный камень (ruby-mcrypt).Кажется, проблема с openssl.На самом деле проблема заключается в том, что Openssl не поддерживает заполнение нулями и использует no-padding или default-openssl-padding.В связи с тем, что вы используете нулевое заполнение в php, вы должны использовать нулевое заполнение также в ruby.

Вывод на моем компьютере для сценария php:

[~/test] ➔ php5 t.php 
6337137fd88148250fd135a43dbeb84a

и для сценария ruby:

[~/test] ➔ ruby t2.rb 
password
6337137fd88148250fd135a43dbeb84a

и моя рубиновая версия:

[~/test] ➔ ruby -version
ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux]

Надеюсь, это поможет.

1 голос
/ 27 августа 2012

если размер ключа не является стандартным на стороне php, вам необходимо заполнить ключ нулями до следующего допустимого размера ключа, чтобы рубиновая сторона работала так:

php_encrypted = string_encoded_with_php_mcrypt

key = "longerthan16butnot24".to_a.pack('a24')
enc = Mcrypt.new(:rijndael_256, :ecb, key, nil, :zeros)
enc.decrypt(php_encrypted)

В этом случае следующийдопустимая длина ключа - 24.

Для: rijndael_256 допустимая длина ключа: 16, 24, 32

. Вы можете получить более подробную информацию об алгоритмах:

Mcrypt.algorithm_info(:rijndael_256
0 голосов
/ 16 июля 2011

если вы можете использовать другие методы шифрования, вы можете попробовать TEA Block Encryption.Я принял метод через Ruby, JS, ActionScript.Он должен работать и с PHP.репозиторий github здесь

...