Php SSL错误SSL3\u获取\u服务器\u证书:证书验证失败

Php SSL错误SSL3\u获取\u服务器\u证书:证书验证失败,php,apache,openssl,Php,Apache,Openssl,升级到PHP5.6后,我尝试通过fsockopen()连接到服务器时出错 服务器(主机)上的证书是自签名的 PHP警告:fsockopen():SSL操作失败,代码为1。OpenSSL错误消息: 错误:14090086:SSL例程:SSL3\u获取\u服务器\u证书:证书验证失败 代码 试过 php.ini openssl.cafile = "/etc/ssl/certs/cacert.pem" 但脚本仍然无法工作 更新 这很有效 echo file_get_contents("/etc/ss

升级到PHP5.6后,我尝试通过
fsockopen()
连接到服务器时出错

服务器(主机)上的证书是自签名的

PHP警告:fsockopen():SSL操作失败,代码为1。OpenSSL错误消息: 错误:14090086:SSL例程:SSL3\u获取\u服务器\u证书:证书验证失败

代码 试过 php.ini

openssl.cafile = "/etc/ssl/certs/cacert.pem"
但脚本仍然无法工作

更新 这很有效

echo file_get_contents("/etc/ssl/certs/cacert.pem");
更新2 错误

PHP警告:stream_socket_client():SSL操作失败,代码为1。OpenSSL错误消息: 错误:14090086:SSL例程:SSL3\u获取\u服务器\u证书:证书验证失败


您是否尝试过使用
stream\u context\u set\u option()
方法

$context = stream_context_create();
$result = stream_context_set_option($context, 'ssl', 'local_cert', '/etc/ssl/certs/cacert.pem');
$fp = fsockopen($host, $port, $errno, $errstr, 20, $context);

此外,请尝试对pem文件使用
file\u get\u contents()
,以确保您有权访问该文件,并确保主机名与证书匹配。

您下载的文件()是来自主要受信任证书颁发机构的根证书束。您说过远程主机有一个自签名SSL证书,所以它没有使用受信任的证书。
openssl.cafile
设置需要指向用于在远程主机上签署SSL证书的CA证书。PHP5.6比以前的PHP版本有所改进,现在可以在默认情况下验证对等证书和主机名()

您需要找到在签署SSL证书的服务器上生成的CA证书,并将其复制到此服务器。如果您使用的是自签名证书,则需要将用于对远程主机的SSL证书进行签名的CA证书添加到您连接的服务器上的受信任存储中,或者使用流上下文为每个请求使用该证书。将其添加到受信任证书是最简单的解决方案。只需将远程主机的CA证书的内容添加到您下载的cacert.pem文件的末尾

上一篇:

fsockopen不支持流上下文,因此请改用stream\u socket\u client。它返回一个可以与fsockopen资源可以使用的所有命令一起使用的资源

这应该是您问题中的代码片段的替代品:

<?php

$contextOptions = array(
    'ssl' => array(
        'verify_peer' => true, // You could skip all of the trouble by changing this to false, but it's WAY uncool for security reasons.
        'cafile' => '/etc/ssl/certs/cacert.pem',
        'CN_match' => 'example.com', // Change this to your certificates Common Name (or just comment this line out if not needed)
        'ciphers' => 'HIGH:!SSLv2:!SSLv3',
        'disable_compression' => true,
    )
);

$context = stream_context_create($contextOptions);

$fp = stream_socket_client("tcp://{$host}:{$port}", $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $context);

if (!$fp) {

    echo "$errstr ({$errno})<br />\n";

}else{
    
    $this->request = 'POST '.substr($this->url, strlen($this->host)).' HTTP/1.1'.$crlf
        .'Host: '.$this->host.$crlf
        .'Content-Length: '.$content_length.$crlf
        .'Connection: Close'.$crlf.$crlf
        .$body;

    fwrite($fp, $this->request);

    while (!feof($fp)) {
        $this->response .= fgets($fp);
    }

    fclose($fp);

}

您提到证书是(由您)自行签署的吗?那么你有两个选择:

  • 将证书添加到您的信任存储(从cURL网站获取
    cacert.pem
    不会做任何事情,因为它是自签名的)
  • 不用费心验证证书:你相信自己,不是吗
以下是PHP中SSL上下文选项的列表:

如果将证书导入信任存储,请将
允许自签名
,或将
验证\u peer
设置为false以跳过验证


我们信任特定证书的原因是因为我们信任其颁发者。由于您的证书是自签名的,因此没有客户端会信任该证书,因为签名者(您)不受信任。如果在签署证书时创建了自己的CA,则可以将CA添加到信任存储中。如果您的证书不包含任何CA,则您不能期望任何人连接到您的服务器。

在我的情况下,我在CentOS 7上,我的php安装指向通过
更新CA信任生成的证书。符号链接是
/etc/pki/tls/cert.pem
,指向
/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
。这只是一个测试服务器,我希望我的自签名证书能够正常工作。所以就我而言

# My root ca-trust folder was here. I coped the .crt file to this location
# and renamed it to a .pem
/etc/pki/ca-trust/source/anchors/self-signed-cert.pem

# Then run this command and it will regenerate the certs for you and
# include your self signed cert file.
update-ca-trust

然后我的一些api调用开始工作,因为我的证书现在是可信的。此外,如果您的ca信任通过yum或其他方式更新,这将重建您的根证书,并且仍然包括您的自签名证书。运行
man update ca trust
以获取有关如何操作的详细信息。:)

在使用Docker处理Ubuntu 16.04时,我遇到了类似的问题。在我的例子中,这是Composer的一个问题,但错误消息(以及由此产生的问题)是相同的

由于以Docker为导向的极简主义基本映像,我丢失了
ca证书
包,而简单的
apt get install ca证书
帮助了我。

添加

$mail->SMTPOptions = array(
'ssl' => array(
    'verify_peer' => false,
    'verify_peer_name' => false,
    'allow_self_signed' => true
));
以前

mail->send()
替换

require "mailer/class.phpmailer.php";


如果您使用的是macOS sierra,PHP版本中会有一个更新。您需要在PHP代码中添加委托.net证书颁发机构(2048)文件。更多信息请查看此处接受的答案

问题出在macOS Sierra的新PHP版本中

请加上

stream_context_set_option($ctx, 'ssl', 'verify_peer', false);

首先,确保您的防病毒软件不会阻止SSL2。

因为我在很长一段时间内都无法解决问题,只有禁用防病毒软件才能帮助我

已经尝试过了。。我找不到文件,你得看看细节。有多种可能的原因,但不使用证书中显示的相同域是常见的原因。您可以使用
curl-v
无误地访问它吗?另外请注意,除非这些版本的openssl已将所有安全补丁进行了后端口,否则您可能需要升级。问题不在于服务器。。它起作用了。导致问题的是客户端,您使用的是哪个操作系统?
echo文件获取内容(“/etc/ssl/certs/cacert.pem”)fsockopen仅支持五个参数。它应该单独使用
fsockopen
。。这太复杂了,我不确定您使用的是什么linux发行版,但请尝试运行
sudo服务apache2 restart
。在将openssl.cafile行添加到php之后,可能需要重新启动apache。ini@clarkk您要连接到的主机,该主机的SSL证书是您拥有CA证书的自签名证书吗?PHP5.6现在在使用fsockopen时验证SSL证书,因此用于签署远程主机SSL证书的CA证书需要在您的主机上受信任
mail->send()
require "mailer/class.phpmailer.php";
require "mailer/PHPMailerAutoload.php";
stream_context_set_option($ctx, 'ssl', 'verify_peer', false);