【问题标题】:Exception handling for openssl decrypt In phpphp中openssl解密的异常处理
【发布时间】:2018-05-05 08:26:03
【问题描述】:

我需要 php 解密算法方面的帮助。

当我在解密函数中传递错误的加密数据时出现错误。所以我需要使用异常处理错误。有可能吗?

我尝试了这段代码,但没有成功

function decrypt($encrypt_data) {
    $key = ENC_KEY;
    $encryption_key = base64_decode($key);
    list($encrypted_data, $iv) = explode('::', base64_decode($encrypt_data), 2);

    try {
      if(openssl_decrypt($encrypted_data, 'aes-256-cbc', $encryption_key, 0, $iv)) {
          throw new customException($encrypted_data);
      }
    }

    catch (customException $e) {
      echo $e->errorMessage();
    }

 }

但是这个函数给了我错误:-

警告:openssl_decrypt():IV 传递的只有 7 个字节长,密码 需要一个精确 16 字节的 IV,在 abc.php 中用 \0 填充

【问题讨论】:

  • 这不是错误,而是警告。不是一回事。该函数本身会将 IV 填充为正确的长度并且仍然可以工作。如果您想修复警告,您可以在使用前验证 IV,并在需要时自行填充。
  • 顺便说一句,如果解密有效,为什么要抛出异常?您实际上也没有保存解密的字符串。
  • @magnus 感谢您的评论。当我传递错误的加密数据时,解密不起作用。我只需要错误(警告)处理,所以我不描述保存或返回数据

标签: php exception encryption error-handling


【解决方案1】:

As Magnus indicates,密钥和 IV 应该是 CBC 模式下 AES 的特定大小。对于 AES-256,密钥大小应为 32 字节,IV 与块大小相同:16 字节。

一般来说,任何语言都会在使用之前验证密钥和 IV 的大小,但是 PHP 有一个讨厌的习惯(对于 OpenSSL 和 mcrypt API),如果它太小或削减它的一部分,就会用零填充它当它太大时。这可能是因为底层 C 库不验证大小,因为键和 IV 作为指针而不是数组或对象传递。

要解决这个问题,您应该确保密钥正好是 32 个随机字节(显然是因为没有警告)并且 IV 正好由 16 个随机字节组成。


请注意,对于 CBC 模式,IV 由 16 个字节组成,这对攻击者来说是完全不可预测的,这是一个安全要求。因此,不建议仅通过自己用零填充 IV 来修复错误。虽然使用 7 个字节作为 IV 不太可能直接导致漏洞利用,但您应该修复协议,而不是依赖代码中的解决方法。

如前所述,其他加密 API(针对不同语言)将严格强制使用正确大小的密钥和 IV;如果您继续使用 7 字节 IV,那么所有这些运行时可能也需要变通方法。

【讨论】:

  • 谢谢 Maarten Bodewes 很好的解决方案
猜你喜欢
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 2013-02-25
  • 2016-02-29
相关资源
最近更新 更多