【发布时间】:2016-09-05 21:43:18
【问题描述】:
我看到 PHP 中的 openssl_* 方法有一些奇怪的行为。 50% 的时间,它会失败,抛出Unknown cipher algorithm,而另外 50% 的时间,它会正确编码我的数据。这是我的代码中相关的 sn-p:
$iv = openssl_random_pseudo_bytes(16);
$hash = openssl_encrypt($raw, "AES-128-CBC", $hashing_secret, OPENSSL_RAW_DATA, $iv);
// send $iv.$hash
使用openssl_get_cipher_methods 给我:
[0] => AES-128-CBC
...
[81] => aes-128-cbc
所以我知道密码可用。此外,$ openssl ciphers 将 AES-128-CBC 列为系统级别的可用密码(但是,我被告知 PHP 捆绑的 openssl 是独立的)
我正在运行 Ubuntu 14.04、php5.5.9-1ubuntu4.14、openssl 1.0.1f 2014 年 1 月 6 日(phpinfo 中列出的版本相同)。如果相关,所有这些代码都通过 nginx/php-fpm 在 Silex 框架下运行。
更新:更多信息...
我做了更多的测试。我写了一个小脚本,它只循环 x 次,对一些数据进行编码。
set_error_handler(function() use (&$errorCount) {
$errorCount++;
});
for ($i = 0; $i < $numTests; $i++) {
$hash = openssl_encrypt($data, "AES-128-CBC", $hashing_secret, OPENSSL_RAW_DATA, $iv);
}
如果我在同一台服务器上运行它(通过php test.php),它会始终如一地运行——即每次都运行$errorCount == 0。这让我相信它是:a) silex 或 b) 阻碍该功能的 fastcgi 进程 - 我已经添加了这些标签。
虽然现在还不确定从这里去哪里......
第二次更新
我做了更多的测试。我将测试脚本卡在 nginx 后面,运行 php-fpm。奇怪的是,要么 a) 它失败了 100% 的时间,要么 b) 它失败了 0 次,而不是两个结果的一点点。这让我相信罪魁祸首是 nginx 或 php-fpm。
【问题讨论】:
-
密钥和 IV 是否完全正确,密钥是 128 位、192 位或 256 位之一,而 iv 是 16 字节?
-
您可以看到我的 IV 有多长 - 它正好是 16 个字节。我使用的密钥是 128 位(16 个字符)
-
您是否检查
openssl_random_pseudo_bytes(16);不返回FALSE,来自文档:成功时返回生成的字节字符串,失败时返回FALSE。 有时这样的例程因为这些没有足够的熵来返回请求的字节。添加这样的检查并记录任何失败可能是值得的。 -
另外:每次都使用相同的密钥吗? “(16个字符)”这句话让我担心,这在不同的语言中意味着不同的东西。加密适用于 8 位字节,而字符很多时候指的是特定的字符编码,例如 UTF-8、UTF-16 等。我个人只相信在所有输入和输出的加密调用之前和之后的十六进制显示。
-
我将密钥设置为“abce...”16 个字符。
标签: php symfony ubuntu openssl silex