file_get_contents():对等证书不匹配

时间:2016-03-16 12:55:16

标签: php

我使用的是PHP 5.5但我不得不更新它,现在我使用的是PHP 5.6.19。

现在,当我尝试与外部API通信时,我收到警告:

  

警告:file_get_contents():对等证书CN = *.domain.com' did not match expected CN= api.domain.com'

以前的PHP版本没有出现过。

    $encryptedEncodedData // this is json encoded
//array, then encrypted by mcrypt with rijndael-128 and finally bin2hex.

    $context = stream_context_create(array(
                        'http' => array(
                            'method' => 'POST',
                            'header' => 'Content-Type: application/json',
                            'content' => $encryptedEncodedData,
                        )
                    ));

    $api = 'https://api.domain.com/service';

    $response = file_get_contents($api, FALSE, $context);

我不知道这个警告的原因是什么。

我决定禁用peer verfy,直到我的管理员修复了cert的问题,然后我更改了$ context:

$context = stream_context_create(array(
                    'http' => array(
                        'method' => 'POST',
                        'header' => 'Content-Type: application/json',
                        'content' => $encryptedEncodedData,
                        'verify_peer'      => false,
                        'verify_peer_name' => false,
                        ), 
                    )
                );

但仍然无法正常工作。我这样做了吗?得到同样的警告。

6 个答案:

答案 0 :(得分:1)

SSL证书似乎有问题。

但是在php 5.6中更改了设置,您可以通过忽略验证来修复此问题,或者当您拥有自签名证书时,allow_self_signed可以相关。

 stream_context_create($ourStuff, ['verify_peer' => false]);

更多信息和设置: http://php.net/manual/en/context.ssl.php

http://php.net/manual/en/function.stream-context-create.php

引用

请注意,禁用验证可能存在安全风险,只有在您知道自己在做什么时才应该这样做。

在较新的php版本(> = 5.6)中,verify_peer的默认值已更改为true。这意味着始终存在安全风险。

正如deceze所指出的那样,只有当你确定所有其他事情都像你自己的php配置一样时才应该这样做:

步骤1:使用openssl CLI工具或您喜欢的任何其他方法测试远程证书是否有效。如果远程证书没问题。

第2步:找出PHP无法接受的原因。如果是因为PHP在验证通配符证书时遇到问题,请查看是否有一些修复。或者,如果是因为PHP没有本地CA存储,这很容易修复。

第3步:禁用对等验证。

答案 1 :(得分:1)

临时固定:

$context = stream_context_create(array(
                    'http' => array(
                        'method' => 'POST',
                        'header' => 'Content-Type: application/json',
                        'content' => $encryptedEncodedData,
                        ),
                    'ssl' => array(
                        'verify_peer'      => false,
                        'verify_peer_name' => false,
                        ),
                    )
                );

谢谢大家

答案 2 :(得分:1)

这对我有用。关键是将'allow_self_signed'设置为TRUE。

    stream_context_set_default(array(
            'ssl'                => array(
            'peer_name'          => 'generic-server',
            'verify_peer'        => FALSE,
            'verify_peer_name'   => FALSE,
            'allow_self_signed'  => TRUE
             )));


    $response = file_get_contents($url, FALSE);

答案 3 :(得分:1)

在php 7.1中有一个非常相似的问题

对我来说,

看起来像个错误:

https://bugs.php.net/bug.php?id=76196

通过已配置的代理向{sll网站调用file_get_contents将让证书检查"滞后"一个人落后。

首次调用file_get_contents所请求网站的证书将被锁定在"为下次通话。这将失败。

所以只有file_get_contents的第一个电话会成功,其余的都会失败。

<?php
$stream_default_opts = [
  'http' => [
    'proxy'=>"tcp://5.9.78.28:3128",
    'request_fulluri' => true,
  ]
];
stream_context_set_default($stream_default_opts);
file_get_contents("https://www.symfony.com", false); 
file_get_contents("https://getcomposer.org", false); 
file_get_contents("https://github.com", false); 

实际结果:

Warning: file_get_contents(): Peer certificate CN=`getcomposer.org' did not match expected CN=`www.symfony.com' in foo.php on line 11
Warning: file_get_contents(https://getcomposer.org): failed to open stream: Cannot connect to HTTPS server through proxy in foo.php on line 11

Warning: file_get_contents(): Peer certificate CN=`github.com' did not match expected CN=`www.symfony.com' in foo.php on line 12
Warning: file_get_contents(https://github.com): failed to open stream: Cannot connect to HTTPS server through proxy in foo.php on line 12

答案 4 :(得分:1)

我知道这很老了,但是我最近才不得不解决这个问题并找到了解决方案,所以我将其发布在网络上以帮助其他人:

我遇到了同样的问题,花了无数个小时寻找答案。我希望我可以通过共享swift_transportexception连接问题的解决方案来帮助开发人员社区。在这里...

对.env文件进行以下调整:

MAIL_DRIVER=sendmail

MAIL_HOST=YOUR_DOMAIN.COM

MAIL_PORT=465

MAIL_USERNAME=YOUR_EMAIL@YOUR_DOMAIN.COM

MAIL_PASSWORD=YOUR_PASSWORD

MAIL_ENCRYPTION=ssl

MAIL_FROM_ADDRESS=YOUR_EMAIL@YOUR_DOMAIN.COM

MAIL_FROM_NAME="${APP_NAME}"

确保您的DNS记录设置为:MX-@-mail.YOUR_DOMAIN.COM-优先级0

答案 5 :(得分:0)

如果您担心安全性,请使用curl而不是file_get_contents。

$url = "https://www.google.com/"
$ch = curl_init();
curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36');
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
$result = curl_exec($ch);

此功能与文件获取内容相同,但不需要您进入安全模式