【问题标题】:Different output between OpenSSL and Mcrypt in PHP - why?PHP 中 OpenSSL 和 Mcrypt 之间的输出不同 - 为什么?
【发布时间】:2013-11-22 10:17:57
【问题描述】:

我目前正在开发一个大型应用程序,其中 Windows 软件需要解密 PHP 脚本生成的字节流。在花费大量时间调整 Windows 应用程序和 PHP 脚本之后,我们终于设法解密了一个使用 Blowfish 算法加密的简单字符串。

在我们的测试过程中,我们同时使用了 Mcrypt 和 OpenSSL,但只有 MCrypt 给出了正确的输出(至少是 Windows 客户端能够理解的输出)。

我们目前正试图了解为什么这两个库的行为不同,以确保我们做的是正确的事情。此外,当我们读到 OpenSSL 现在被强烈推荐并提供比 MCrypt 更多的功能时,我们现在更愿意使用 OpenSSL。

为了定位错误,我们使用 MCrypt 和 OpenSSL 进行了一个非常简单的测试,该测试使用相同的输入但产生不同的输出。请注意,我们仅将 null IV 用于测试目的,我们知道这样做并不安全。我们在 CBC 模式下使用 Blowfish,具有 256 位二进制密钥。

MCrypt 密码:

    $key = hash ("sha256", "toto", true);
    $alg  = MCRYPT_BLOWFISH;
    $mode = MCRYPT_MODE_CBC;
    $data = "tata";
    $encrypted = mcrypt_encrypt($alg, $key, $data, $mode, "\0\0\0\0\0\0\0\0");
    $encrypted = base64_encode($encrypted);

输出(Windows客户端正确理解): kc7bO7jTWF8=

OpenSSL 代码:

   $key = hash ("sha256", "toto", true);
   $method = "BF-CBC";
   $data = "tata\0\0\0\0"; //Completely different results if we don’t pad the input ourself
   $encrypted = openssl_encrypt($data, $method, $key, true, "\0\0\0\0\0\0\0\0");
   $encrypted = base64_encode($encrypted);

输出kc7bO7jTWF/+NdPlZPBxMw==

如您所见,两个输出以相同的值开头,但 OpenSSL 输出稍大(16 字节)。为什么 ?如果我们不手动填充输入,我们会得到一个不同的输出,它似乎具有有效的大小,但与 MCrypt 不同:

输出iCug+W0s2lc=

我们怀疑存在填充问题,但目前无法找到解决方案。

感谢任何提示!

【问题讨论】:

标签: php encryption openssl mcrypt


【解决方案1】:

经过一些研究,似乎 MCrypt 用零字节填充输入,而 OpenSSL 使用 PKCS#7 填充,这解释了不同的输出。通过在 PHP 端移除手动填充并在 Windows 端实现 PKCS#7 填充,我们设法获得了相同的结果。

【讨论】:

    猜你喜欢
    • 2011-04-04
    • 2015-06-17
    • 2014-01-29
    • 1970-01-01
    • 2018-08-18
    • 2021-11-07
    • 2012-10-13
    • 1970-01-01
    • 2017-09-28
    相关资源
    最近更新 更多