【问题标题】:PHP PKCS7 Padding bugPHP PKCS7 填充错误
【发布时间】:2014-07-28 13:20:46
【问题描述】:

我正在尝试将 PKCS7 填充应用于我的 PHP 代码。我从这个要点派生了我的代码

https://gist.github.com/Halama/5956871

块大小预计为 16 字节。 数据为“密码”,长度为 8 个字节。 拿到pad后,会在要加密的数据末尾追加。

$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, $thisMCRYPT_MODE_CBCmode);
$pad = $blockSize - (strlen($data) % $blockSize);
$data = $data . str_repeat(chr($pad), $pad);

问题是存在(很多)数据无法解密的实例。

下面提供的是 base64 编码的示例数据。解码样本的前 16 个字节代表 IV

工作: cjg1RYWxlc8bDH2de43t0bv1ug36i8ayjWDQTela938=(焊盘长度:8)

不工作: 9wWI+MyYj5ZVj2sC4xr7EgOsgNSoeTZW1yM8ddmqg18=(焊盘长度: 122)

上面提到的pad长度是用这个来检索的

$pad = ord($data[strlen($data) - 1]);

我正在使用 mcrypt_enrypt 加密字符串“密码”。我用于 mcrypt 的密钥是

lgbsVE+qVO1P2ue0iCjrTPMU5hKX9aHE7r1aUUeqFag=

【问题讨论】:

    标签: php encryption padding mcrypt pkcs#7


    【解决方案1】:

    填充/取消填充例程看起来正确。它没有提供防止填充值高于块大小的保护措施。

    如果使用错误的密钥对密文进行解密,或者密文已损坏(对于短密文,即使 IV 不正确),结果将是具有看似随机数据的(填充)明文。所以在不正确结果的unpadding过程中,最后一个字节可以是任意随机值。

    为防止此类故障,请在密文上使用 MAC 值,最好使用不同的密钥。目前,问题不太可能是(取消)填充例程。

    【讨论】:

    • 失败?您是指“使用错误的密钥..密文已损坏”失败吗?还是您指的是“填充值高于块大小”失败?我在问题中提到的关键是正确的。这是我在加密两个样本时使用的相同密钥。
    • 您使用的填充/取消填充方案似乎相当普遍。除非我大错特错,如果最后一个字节的值是 122,你只能得到这个错误的结果。这应该很容易检查。 请注意,我不能 100% 确定如果您的明文包含 00 值字符会发生什么。
    【解决方案2】:

    解决了。 base64 编码数据中的“+”符号在通过 http 传输时被转换为空格,从而导致不同的值。

    我所做的是客户端将二进制数据编码为 base64 并通过 urlencode() 函数传递。 PHP 端使用 rawurldecode 处理数据,因此它会忽略“+”号。

    【讨论】:

      猜你喜欢
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-28
      相关资源
      最近更新 更多