Вот мои требования:
Мне нужно зашифровать строку в PHP с помощью AES-шифрования (включая случайный iv), Base64-кодировать ее, затем URL-кодировать ее так, чтобы ее можно было передать в качестве параметра URL.
Я пытаюсь получить тот же результат и в PHP, и в Ruby, но у меня ничего не получается.
Вот мой PHP код:
function encryptData($data,$iv){
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
$iv_size = mcrypt_enc_get_iv_size($cipher);
if (mcrypt_generic_init($cipher, 'g6zys8dlvvut6b1omxc5w15gnfad3jhb', $iv) != -1){
$cipherText = mcrypt_generic($cipher,$data );
mcrypt_generic_deinit($cipher);
return $cipherText;
}
else {
return false;
}
}
$data = 'Mary had a little lamb';
$iv = '96b88a5f0b9efb43';
$crypted_base64 = base64_encode(encryptData($data, $iv));
Вот мой Ruby код:
module AESCrypt
def AESCrypt.encrypt(data, key, iv)
aes = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
aes.encrypt
aes.key = key
aes.iv = iv
aes.update(data) + aes.final
end
end
plaintext = "Mary had a little lamb"
iv = "96b88a5f0b9efb43"
@crypted = AESCrypt::encrypt(plaintext, "g6zys8dlvvut6b1omxc5w15gnfad3jhb", iv)
@crypted_base64 = Base64.encode64(@crypted)
@crypted_base64_url = CGI.escape(@crypted_base64)
Самое обидное, что оба примера кода выдают похожие, но не идентичные хэши. Например, приведенный выше код генерирует (в кодировке base64, не в кодировке URL):
PHP: /aRCGgLBMOOAarjjtfTW2Qg2OtbPDLhx3KmgfgMzDJU=
Ruby: /aRCGgLBMOOAarjjtfTW2XIZhZ9VjBx8PdozxSL8IE0=
Кто-нибудь может объяснить, что я делаю не так? Кроме того, мне проще (поскольку я работаю с Ruby, а не с PHP) исправлять код Ruby, а не PHP. Так что если вы хотите предложить решение на Ruby, которое будет хорошо сочетаться с PHP, я буду очень признателен.
О, и еще, в продакшене iv действительно будет случайным, но для этого примера я установил его постоянно одинаковым, чтобы можно было сравнить результаты.
EDIT:
Благодаря ответу Eugen Rieck я пришел к решению. Ruby вставляет блоки, но PHP этого не делает, и вам приходится делать это вручную. Измените код PHP на следующий, и вы получите зашифрованные строки, которые вышеприведенный код Ruby сможет легко расшифровать:
$iv = '96b88a5f0b9efb43';
$data = 'Mary had a little lamb';
function encryptData($data,$iv){
$key = 'g6zys8dlvvut6b1omxc5w15gnfad3jhb';
$padded_data = pkcs5_pad($data);
$cryptogram = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $padded_data, MCRYPT_MODE_CBC, $iv);
return $cryptogram;
}
function pkcs5_pad ($text, $blocksize){
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}