这是我的要求:
我需要使用 AES 加密(包括随机 iv)对 PHP 中的字符串进行加密,对其进行 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)
令人愤怒的是两个代码示例都产生similar但哈希值不相同。例如,上面的代码生成(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);
}