这个问题是我上一个问题的延续,关于How to make Ruby AES-256-CBC and PHP MCRYPT_RIJNDAEL_128 play well together。我现在已经开始工作了,但我仍在努力转向另一个方向。PHP 生成的密码似乎包含提供的所有信息,但我无法获得 Ruby 代码来解密它而不会出错。
这是我用来生成密码的 PHP 代码:
$cleartext = "Who's the clever boy?";
$key = base64_decode("6sEwMG/aKdBk5Fa2rR6vVw==\n");
$iv = base64_decode("vCkaypm5tPmtP3TF7aWrug==");
$cryptogram = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $cleartext, MCRYPT_MODE_CBC, $iv);
$result = base64_encode($cryptogram);
print "\n'$result'\n";
RESULT
'JM0OxMINPTnF1vwXdI3XdKI0KlVx210CvpJllFja+GM='
然后这是在 Ruby 中解密的尝试:
>> cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
>> cipher.key = Base64.decode64("6sEwMG/aKdBk5Fa2rR6vVw==\n")
>> cipher.iv = Base64.decode64("vCkaypm5tPmtP3TF7aWrug==")
>> cryptogram = Base64.decode64('JM0OxMINPTnF1vwXdI3XdKI0KlVx210CvpJllFja+GM=')
>> cleartext = cipher.update(cryptogram)
=> "Who's the clever"
>> cleartext << cipher.final
OpenSSL::Cipher::CipherError: bad decrypt
from (irb):100:in `final'
from (irb):100
真正令人沮丧的是,有可能从该加密字符串中获取整个明文。重复上述步骤,但在密码中添加一个无意义的填充:
>> cleartext = cipher.update(cryptogram + 'pad')
=> "Who's the clever boy?\000\000\000\000\000\000\000\000\000\000\000"
>> cleartext << cipher.final
OpenSSL::Cipher::CipherError: bad decrypt
from (irb):119:in `final'
from (irb):119
在我的实际用例中,明文是结构化的(一个 JSON 字符串,因为你问了),所以我感觉很舒服,我可以告诉使用这个方案并检测加密不佳的输入而不执行cipher.final
. 但是,我不能容忍我的代码中出现这种混乱,所以我想了解如何让 ruby 代码优雅地处理最后一个块。