我在 PHP中使用openssl_ *方法看到一些奇怪的行为. 50%的时间,它会失败,抛出未知密码算法,另外50%的时间,它会正确编码我的数据.以下是我的代码中的相关代码段:
$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密码在系统级别列出了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,$iv);    
}

如果我在同一个服务器上运行(通过PHP test.PHP),它一直运行 – 即每次都有$errorCount == 0.这导致我相信它是:a)silex或b)阻止功能的fastcgi进程 – 我添加了这些标签.

不知道从哪里去,现在,虽然…

第二次更新

我做了一些更多的测试.我把测试脚本放在Nginx后面,运行PHP-fpm.这里奇怪的是,或者a)100%的时间失败,或b)它失败了0次,而不是两个结果的一点点.这使我相信它是Nginx或PHP-fpm是罪魁祸首.

这看起来可能是OpenSSL错误锁定错误.您应该确保在同一进程空间中任何时候只有一个OpenSSL对象被使用.

要验证,运行测试脚本,以便它是唯一使用OpenSSL的脚本. 50%的时间仍然失败吗?还是只有在脚本的多次并发访问时才会发生故障?

如果仍然发生,它几乎必须是PHP-fpm中的错误 – 它正在实例化功能,而不是正确清除其数据区域,直到出现错误.在这种情况下,我希望它每两个呼叫失败一次,而不是“平均50%”,而是每次偶数号呼叫一次.在这种情况下,我会尝试使用不同版本的OpenSSL.

要锁定openssl,您可以尝试使用flock并实例化一个锁定文件以供SSL功能使用(首先,您检查锁可用,然后运行该功能并解锁).尝试这个,看看它是否有效.如果这样做,您可以查看更有效的方法 – 例如,您可以使用MysqL LOCK()或semaphore(如果可用).

洞穴探险

5.5.9中的错误行为可以在ext / openssl / openssl.c中找到,并且抛出的错误是初步检查之一.还没有惊喜:

/* {{{ proto string openssl_encrypt(string data,string method,string password [,long options=0 [,string $iv='']])
   Encrypts given data with given method and key,returns raw or base64 encoded string */
PHP_FUNCTION(openssl_encrypt)
{
    long options = 0;
    char *data,*method,*password,*iv = "";
    int data_len,method_len,password_len,iv_len = 0,max_iv_len;
    const EVP_CIPHER *cipher_type;
    EVP_CIPHER_CTX cipher_ctx;
    int i=0,outlen,keylen;
    unsigned char *outbuf,*key;
    zend_bool free_iv;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSrmlS_CC,"sss|ls",&data,&data_len,&method,&method_len,&password,&password_len,&options,&iv,&iv_len) == FAILURE) {
        return;
    }
    cipher_type = EVP_get_cipherbyname(method);
    if (!cipher_type) {
        PHP_error_docref(NULL TSrmlS_CC,E_WARNING,"UnkNown cipher algorithm");
        RETURN_FALSE;
    }

所以我们可以假设EVP_get_cipherbyname(method)返回一个false.

除了它是标准的SSL功能外.我发现这个很简洁(很可能是过时的)reply,这似乎表明食谱中有一些面膜汁.但是这并不能解释为什么每两个功能失败一次.

该函数是here on github.它初始化OpenSSL,它通过一个ancillary function获取方法名称,它将返回一个指向非空的内存的指针.

我有一个远方的假设,该函数随机返回类似于0或81(由于两个字符串都在您的密码列表输出中,索引为0和81),0等于NULL,因此失败.看来它不能这样工作,它也应该在CLI中这样做.但只是为了确保,验证是否只是特定的密码失败(例如AES-256-CBC工作).

另一种可能性是它是失败的OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS,NULL)调用.如果这个测试(在Ubuntu;其他平台的行为不同)失败,可能会发生这种情况:

int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once,void (*init)(void))
{
    if (pthread_once(once,init) != 0)
        return 0;

    return 1;
}

这再次表明libcrypto内部存在一些共享资源冲突.

作为另一个测试,我建议你不要调用随机字节IV初始化,并尝试用固定的IV;那是因为我还偶然发现了this note年,它指向的资源略微不同于我的想法,但足够接近让我有所反应:

It appears that openssl_random_pseudo_bytes(),which calls openssl,
causes the underlying libcrypto to invoke a callback that was
established prevIoUsly by Postgresql library as part of the lock
portability callbacks for multi-threading of openssl.

Some information on the topic can be found here
07006

如果HHVM openssl扩展没有建立这些相同的回调,可能会导致调用错误的回调.

我要执行的下一个测试是时间允许的,是在上述故障点中放置警报(以静态syslog调用的形式),以准确地确定哪个测试失败…如果我可以安装相同的设置就像你在虚拟机上一样,我可以重现同样的怪异行为.

php – openssl encypt / decrypt不一致的工作/失败的更多相关文章

  1. ios – 找不到lcrypto的库

    我正在尝试构建iOSAllJoyn项目,但我遇到了OpenSSL集成的问题.我一直在看这些方向:https://allseenalliance.org/docs-and-downloads/documentation/configuring-build-environment-ios-and-osx#unique_16我已经按照指示一直到XcodeIDEBuild,但现在我收到一个错误,上面写着:

  2. 从iOS应用程序发送帖子到PHP脚本不工作…简单的解决方案就像

    我之前已经做了好几次了但是由于某些原因我无法通过这个帖子…我尝试了设置为_POST且没有的变量的PHP脚本……当它们未设置为发布时它工作精细.这是我的iOS代码:这里是PHP的一大块,POST变量不在正确的位置?我想这对于更有经验的开发人员来说是一个相当简单的答案,感谢您的帮助!解决方法$_POST是一个数组,而不是一个函数.您需要使用方括号来访问数组索引:

  3. swift学习2 元组 tuples

    swift中出现了一种新的数据结构,非常牛掰的元组tuples如果懂PHP的猿,会发现这个元组和PHP的数组非常类似,同样是可以默认不指定key,也可以指定key目前的学习疑问是,如何进行元组的遍历?

  4. 尝试使用swift mailer,gmail smtp,php发送邮件

    这里是我的代码:在运行时出现此错误…

  5. 我的Android项目的FIPS合规性

    我正在开发一个与安全相关的项目,并且必须确保它符合FIPS标准.根据我的理解,FIPS合规性是硬件和软件级别的合规性.目前有2款三星Android设备符合FIPS标准,即它们在硬件和软件级别都具有合规性.我的问题如下:–1)如果我想让我的Android应用程序符合FIPS标准,如果我在我的项目FIPS兼容中使用了唯一的加密模块,这就够了吗?

  6. 在Android上移植C lib / app

    我想将几个C/C++库移植到Android,它的可行性如何例如OpenSSL可以移植或者假设一个依赖于OpenSSL的应用程序,当我认为自己拥有libssl.so时,将它移植到Android的最佳方式是什么?什么是可用的工具,例如ScratchBox,还有其他选择吗?

  7. 如何使用Android中的Keytool为W7 32bit生成Keyhash(Facebook)

    name=openssl-0.9.8k_WIN32.zip.然后解压缩文件并运行以下命令:DON是我的系统名称,应替换为您的系统名称.

  8. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  9. jQuery的Cookie封装,与PHP交互的简单实现

    下面小编就为大家带来一篇jQuery的Cookie封装,与PHP交互的简单实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部