CentOS PHP curl 无法协商一组可接受的安全参数
Posted
技术标签:
【中文标题】CentOS PHP curl 无法协商一组可接受的安全参数【英文标题】:CentOS PHP curl unable to negotiate an acceptable set of security parameters 【发布时间】:2016-02-01 14:03:33 【问题描述】:在 Ubuntu 14.04.3 上,此代码运行良好:
$url_login = "https://test.example.com/login.do";
$cert_file = '/var/www/html/test/cert.pem';
$ssl_key = '/var/www/html/test/cert_private.pem';
$post_fields = 'userAction=1&cancelReason=&cancelType=&account=&memoType=&userText=&userid=99999999&password=xxxxxxxxxxxxxxxx';
$ch = curl_init();
$options = array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HEADER => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
CURLOPT_VERBOSE => 0,
CURLOPT_URL => $url_login ,
CURLOPT_SSLCERT => $cert_file ,
CURLOPT_SSLCERTTYPE, 'PEM',
CURLOPT_SSLKEY => $ssl_key,
CURLOPT_COOKIESESSION => 1,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_fields
);
curl_setopt_array($ch , $options);
$output = curl_exec($ch);
Ubuntu 上的 php 使用 curl 和 openssl。
在 Centos 7 上如果失败:
Curl Error : SSL peer was unable to negotiate an acceptable set of security parameters.
curl 和 nss 在这里。
“cert.pem”仅包含带有证书链的客户端证书,“cert_private.pem”包含不受密码保护的私钥。 (-----开始 RSA 私钥-----)。
我怎样才能让上面的 PHP 代码同时工作? curl 的 openssl 和 nss 实现?
【问题讨论】:
【参考方案1】:如何纠正:
CURLOPT_SSLCERTTYPE, 'PEM',
到
CURLOPT_SSLCERTTYPE => 'PEM',
?
【讨论】:
您能否发布您的证书的密钥类型、签名(哈希)算法?您是否检查了 HTTP 服务器配置(它允许使用哪些密码套件)?【参考方案2】:我在使用 nss 的客户端证书身份验证时也遇到过这个问题,而 openssl 工作正常。
经过大量测试,这是我与我们尝试联系的服务器建立的:
使用带有客户端证书的 TLS v1.2(某些情况下为默认)的 curl 失败 curl 使用 TLS v1.2 和服务器需要的客户端证书,但客户端未使用,连接成功。但是客户端未通过身份验证。 curl 使用带有客户端证书的 TLS v1.0 成功无论密码套件如何,都会发生上述情况,通常我们使用的是 rsa_aes_256_cbc_sha_256。
快速解决方法是强制使用 TLS v1.0:
CURLOPT_SSLVERSION => 4,
显然这并不理想,您的服务器可能不支持它。
另一个选择是用 openssl 甚至 GnuTLS(虽然我没有测试过后者)而不是 nss 来编译 curl。同样,这可能不是一个选择。
到目前为止,这表明 NSS 存在问题。如果进一步调试产生任何有用的信息,我会更新这个答案。
仅供参考,这是在命令行中使用 curl 的完整错误信息:
* NSS error -12227 (SSL_ERROR_HANDSHAKE_FAILURE_ALERT)
* SSL peer was unable to negotiate an acceptable set of security parameters.
* Closing connection 0
curl: (35) SSL peer was unable to negotiate an acceptable set of security parameters.
2015 年 11 月 24 日更新: 使用 Wireshark 和 ssltap 进行的进一步测试显示初始握手成功,并且连接到达客户端发送 ChangeCipherSpec,然后是其加密的“完成”消息。
然后,服务器应解密客户端的“完成”消息,验证哈希和 MAC,并以自己的加密“完成”消息进行响应。相反,此时服务器正在响应“handshake_failure”。
这应该提供关于 NSS 失败的线索。
Chrome、Openssl 和 Charles Proxy 都可以使用客户端证书进行身份验证。 Firefox(使用 NSS)和 curl(使用 NSS)此时都失败了。
2015 年 11 月 27 日更新:服务器运营团队提供的其他信息表明,这可能是不合规服务器的问题。只有在某些情况下使用 TLS 1.2 时才会出现此问题。这可以解释为什么某些 SSL 库(例如 OpenSSL)足够灵活,可以绕过它。
NSS 在遵守 RFC 方面可能更加严格。如果/当我们从管理服务器的运营团队那里听到更多消息时,我会更新答案。
2017-01-25 更新:网络服务器软件和负载平衡器是为特定银行的支付网关定制的。我们最近再次尝试使用新客户端,服务器现在似乎可以与使用 NSS 或 OpenSSL 构建的 Curl 一起使用,并且不再看到错误。总之:解决方法是使用不同的 SSL 库并等待开发人员修复服务器软件。
【讨论】:
如果这仍然相关,如果有人感兴趣,我可以提供一些具体信息。以上是关于CentOS PHP curl 无法协商一组可接受的安全参数的主要内容,如果未能解决你的问题,请参考以下文章
您的要求无法解决为 pinterest API 的一组可安装软件包
您的要求无法解析为一组可安装的软件包(Composer 更新)
Composer 更新 - 您的要求无法解析为一组可安装的软件包