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

Har*_*rry 4 php aes objective-c mcrypt commoncrypto

我试图解码从服务器返回的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);
}
Run Code Online (Sandbox Code Playgroud)

和编码数据的例子

3KD+zb/2u5gGEWvOy0Q0nSQE9pbQZmg27iN6WLiO/Af9YjN8MhHOb8TMa5uETaab
Run Code Online (Sandbox Code Playgroud)

当我使用ECB(MCRYPT_MODE_ECB)进行解码时,它只解码数据的开头并且其余部分无法读取

"Please input yo??????g|??*P?Te???  R?B
Run Code Online (Sandbox Code Playgroud)

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

??0?=v??????.3ur username and password again"
Run Code Online (Sandbox Code Playgroud)

结果应该是(在Objective-c中使用CommonCryptor获得的mac):

"Please input your username and password again"
Run Code Online (Sandbox Code Playgroud)

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

Kyb*_*rek 6

请查看维基百科文章.了解ECB和CBC如何解密.如果ECB是使用的模式,您将正确解密所有文本.似乎密码使用CBC,因为它使用先前的密文+当前密文+解密函数来获取原始文本.这就是您正确解码第二个块的原因.

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

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