使用PKCS7填充编码的AES 256数据有一半ECB和一半CBC块


AES 256 with PKCS7 padding encoded data have half ECB and half CBC block

我试图解码从服务器返回的php数据:我知道数据AES 256解码并有PKCS7填充,但无法找出它使用的块模式

下面是我的PHP函数:
public function decode($data)
{
    //AES decode
    $iv = mcrypt_create_iv(GEServerConnection::FBENCRYPT_BLOCK_SIZE, MCRYPT_RAND);
    $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->cryptKey, base64_decode($data), MCRYPT_MODE_ECB, $iv);
    //return $data;
    $len = strlen($data);
    $pad = ord($data[$len - 1]);
    return substr($data, 0, - $pad);
}

和编码数据示例

3KD+zb/2u5gGEWvOy0Q0nSQE9pbQZmg27iN6WLiO/Af9YjN8MhHOb8TMa5uETaab

当我用ECB (MCRYPT_MODE_ECB)解码时,它只解码数据的开始,其余部分不可读

"Please input yo��޸̓��g|��*P�Te���  R�B

,当用CBC (MCRYPT_MODE_CBC)模式解码时,开始不可读

��0�=v������.3ur username and password again"

结果应该是(我在mac上使用CommonCryptor在objective-c):

"Please input your username and password again"

有人知道什么是错的,或者如何以正确的方式解码?

请查看维基百科的文章。看看欧洲央行和加拿大央行是如何解密的。如果使用ECB模式,则可以正确地解密所有文本。该密码似乎使用了CBC,因为它使用了以前的密文+当前的密文+解密功能来获得原始文本。这就是你正确解码第二个块的原因。

为什么第一个块解码错误?这是因为您需要提供正确的初始化向量。它必须与用于加密的相同。我们很幸运,我们知道ECB解码了第一个块,因为ECB不使用初始化向量。

答案很简单:使用零初始化向量的CBC(所有字节都是零),因为现在您的随机IV将第一个块更改为错误输出。