加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

第二部分:如何使Ruby AES-256-CBC和PHP MCRYPT_RIJNDAEL_128一

发布时间:2020-12-16 22:10:57 所属栏目:百科 来源:网络整理
导读:这个问题是我最后一个问题的延续,关于 How to make Ruby AES-256-CBC and PHP MCRYPT_RIJNDAEL_128 play well together.我现在有工作,但我仍然在努力去走另一个方向. PHP生成的密码似乎具有提供的所有信息,但是我无法获取Ruby代码来解密它,没有错误. 以下是
这个问题是我最后一个问题的延续,关于 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?0000000000000000000000"
  >> cleartext << cipher.final
  OpenSSL::Cipher::CipherError: bad decrypt
   from (irb):119:in `final'
   from (irb):119

在我的实际使用情况下,明文是结构化的(一个JSON字符串,因为你问),所以我觉得很舒服,我可以告诉使用这个方案,并检测不好的加密输入,而不执行cipher.final.但是,我不能容忍这种在我的代码中的这种类型,所以我想了解如何使ruby代码优雅地处理最终的块.

解决方法

问题是mcrypt没有填充最后一个块,而Ruby的OpenSSL绑定使用默认的OpenSSL填充方法,即PKCS填充.我从OpenSSL文档中的描述不能真正改进:

PKCS padding works by adding n padding
bytes of value n to make the total
length of the data a
multiple of the block size. Padding is
always added so if the data is already
a multiple of the block size n will
equal the block size. For example if
the block size is 8 and 11 bytes are
to be encrypted then 5 padding bytes
of value 5 will be added.

在加密之前,您需要手动将适当的填充添加到PHP中的明文末尾.要做到这一点,在加密之前通过PHP侧的pkcs5_pad函数传递$cleartext(通过16作为块大小).

function pkcs5_pad ($text,$blocksize)
{
    $pad = $blocksize - (strlen($text) % $blocksize);
    return $text . str_repeat(chr($pad),$pad);
}

如果您还以另一种方式(在Ruby中加密并使用mcrypt进行解密),则必须在解密之后删除填充字节.

旁注:即使明文已经是块大小(整个填充块)的倍数,你必须添加填充的原因是,当您解密时,您知道最后一个块的最后一个字节总是数量的填充.否则,你无法区分明文与单个填充字节和明文之间的差异,没有填充字节刚刚结束的值0x01.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读