【问题标题】:SSL certificate issue unable to get local issuer certificateSSL 证书问题无法获取本地颁发者证书
【发布时间】:2018-06-20 12:30:06
【问题描述】:

我正在尝试将数据发布到支付网关 API。它需要 xml 格式的发布数据。我有以下代码:

<?php
$requestUrl = 'https://api.given.bypg'; //$block->getPaymentUrl();

$amount = 100; // $block->totalOrderAmount()*100; 

$approveUrl = $block->approveUrl();
$cancelUrl =  $block->cancelUrl();
$declineUrl = $block->declineUrl();


$merchant = 'mydomain.com'; 
//$amount = '100'; // in cents. 1$ = 100cents. 
$currency = '840'; // for dollar
$description = 'Happy customers is what we make.';
$merchantId = 'Nobel106513';
?>

<?php
echo $requestUrl;
$xml_data = '<TKKPG>
<Request>
<Operation>CreateOrder</Operation>
<Language>EN</Language>
<Order>
<OrderType>Purchase</OrderType>
<Merchant>'.$merchantId.'</Merchant>
<Amount>'.$amount.'</Amount>
<Currency>'.$currency.'</Currency>
<Description>'.$description.'</Description>
<ApproveURL>'.$approveUrl.'</ApproveURL>
<CancelURL>'.$cancelUrl.'</CancelURL>
<DeclineURL>'.$declineUrl.'</DeclineURL>
</Order>
</Request>
</TKKPG>';

$ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $requestUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60000);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);//My post data
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_CAPATH, "/etc/apache2/ssl/m4/mydomain.com.crt");
        curl_setopt($ch, CURLOPT_CAINFO, "/etc/apache2/ssl/m4/mydomain.com.crt");
        curl_setopt($ch, CURLOPT_CERTINFO, 1);

        $headers = [];
        array_push($headers, 'Content-Type: text/xml;charset=UTF-8');
        //array_push($headers, 'SoapAction: *');
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        $content = trim(curl_exec($ch));
        var_dump($content);
        var_dump(curl_getinfo($ch));
        var_dump(curl_errno($ch));
        var_dump(curl_error($ch));
        curl_close($ch);
  1. var_dump($content); 的输出为空''。
  2. var_dump(curl_getinfo($ch)); 的输出。

    数组(大小=26)
    'url' => 字符串'https://api.given.bypg'
    'content_type' => 空
    'http_code' => int 0
    'header_size' => int 0
    'request_size' => int 0
    '文件时间' => int -1
    'ssl_verify_result' => int 1
    'redirect_count' => int 0
    'total_time' => 浮动 0.488533
    'namelookup_time' => 浮动 0.028558
    'connect_time' => 浮动 0.256858
    'pretransfer_time' => 浮动 0
    'size_upload' => 浮动 0
    'size_download' => 浮动 0
    'speed_download' => 浮动 0
    'speed_upload' => 浮动 0
    'download_content_length' => 浮动 -1
    'upload_content_length' => 浮动 -1
    'starttransfer_time' => 浮动 0
    'redirect_time' => 浮动 0
    'redirect_url' => 字符串'' (长度=0)
    'primary_ip' => 字符串'91.227.244.57'(长度=13)
    'certinfo' =>
    数组(大小=0)
    空
    'primary_port' => int 8444
    'local_ip' => 字符串'192.168.100.64'(长度=14)
    'local_port' => int 53456

  3. var_dump(curl_errno($ch)); 的输出:int 60

  4. var_dump(curl_error($ch)); 的输出:

    string 'SSL 证书问题:无法获取本地颁发者证书'(长度=63) 正如 curl_getinfo() 所见,API 似乎没有返回任何数据。请帮助我,我已经看到了社区中建议的几乎所有解决方案。

我已经编辑了我的php.ini 文件以提供从 curl 网站下载的证书的路径。但这也不起作用。

【问题讨论】:

  • 该错误表示 /etc/apache2/ssl/m4/mydomain.com.crt 不包含签署 HTTPS 服务器证书的 CA 证书。您需要添加它们。
  • @Oleg 对不起,我没明白。我从我的支付网关获得了这个证书。你能不能再详细点。感谢您的回复。

标签: ssl curl ssl-certificate php-curl


【解决方案1】:

我的 API 提供商向我提供了支持,他们指出了我的方法中缺少的东西。对于他们的网关,我需要在 curl 请求中加载保护这些密钥的私钥、公钥和密码。解决方法如下:

/*ssl crts*/
$twpg_cert_file = "/etc/apache2/ssl/m4/mydomain.com.crt";
$twpg_key_file = "/etc/apache2/ssl/m4/mydomain.com.key";
$twpg_key_password = '';
/*ssl crts*/
$ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $requestUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60000);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);//My post data
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_SSLCERT,  $twpg_cert_file);
        curl_setopt($ch, CURLOPT_SSLKEY, $twpg_key_file);
        curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $twpg_key_password);
        curl_setopt($ch, CURLOPT_CERTINFO, 1);
        $headers = [];
        array_push($headers, 'Content-Type: text/xml;charset=UTF-8');
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        $content = trim(curl_exec($ch));
        curl_close($ch);

现在一切都按预期进行。

【讨论】:

    【解决方案2】:

    当您连接到服务器以建立安全连接时,您作为客户端会在与它的对话开始时获得服务器的证书。此证书及其私钥用于建立安全连接。您的客户端希望确保服务器的证书是可信的,并且不是由中间人攻击者创建的。因此,您的客户端需要拥有签署服务器证书的 CA 证书。上面的错误意味着客户端试图找到服务器的证书颁发者(或链中的颁发者之一)但没有找到。它试图找到它的位置是在指定的/etc/apache2/ssl/m4/mydomain.com.crt 文件中。您有两个选择:将 CA 证书添加到文件中,或者通过将 CURLOPT_SSL_VERIFYPEER 设置为 false 来禁用服务器证书验证(不安全)。

    【讨论】:

    • 我已将我的 .csr .crt 和 .key 文件放在 /etc/apache2/ssl/m4/ 中。还有什么需要和做什么?
    • 您需要将签署服务器证书的 CA 证书放到 /etc/apache2/ssl/m4/mydomain.com.crt 文件中,而不是 /etc/apache2/ssl/m4/ 目录中。
    • 下一步:您指定了 CURLOPT_SSL_VERIFYHOST=2。来自 curl doc:当 CURLOPT_SSL_VERIFYHOST 为 2 时,该证书必须指示服务器是您要连接的服务器,否则连接失败。简而言之,这意味着证书中的名称必须与您操作的 URL 中的名称相同。您的证书符合上述条件吗?
    • 建议尝试一个一个地删除选项失去安全性,直到它开始工作,然后你就会知道哪个检查失败
    • 好的,我会这样做的。
    猜你喜欢
    • 2019-04-12
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 2021-08-30
    • 2019-09-03
    相关资源
    最近更新 更多