6

我们的网站最近从 http 转移到 https。它有我们的客户调用的 REST API 调用,现在无法正常工作:

SSL 之前的 cURL(工作):

$ch = curl_init();

curl_setopt($ch,CURLOPT_URL,$api_call_url);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

$result = curl_exec($ch);

curl_close($ch);

SSL后的cURL(不工作):

$ch = curl_init();

curl_setopt($ch,CURLOPT_URL,$api_call_url);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, "/customers_path_on_their_server/to/our_cacert_they_exported_via_firefox.crt");   //X.509 Certificate

$result = curl_exec($ch);

curl_close($ch);

除了要求客户端在他们的 REST 集成代码上添加 CURLOPT_SSL_VERIFYPEER、CURLOPT_SSL_VERIFYHOST、CURLOPT_CAINFO 之外,我是否需要在我们的服务器上设置任何内容?

我真的是 https 的新手,我不知道我需要搜索的确切术语是什么,已经搜索了几个小时的 cURL SSL...

顺便说一句,如果该信息很重要,我们的网站正在使用亚马逊 ec2 托管...

这是返回的 cURL 错误:

 error:SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

卷曲版本:7.21.6

SSL 版本:OpenSSL/1.0.0e

4

2 回答 2

7

不要像其他人经常建议的那样关闭对等和主机验证。 对于真正的问题,这是一个不安全的解决方法。这些功能的存在是有充分理由的:因此您可以通过第 3 方相信您正在连接的系统是您所期望的。

首先查找您的操作系统是否包含证书目录。通常会包括证书颁发机构。例如,在 Ubuntu 上,它通常位于目录/etc/ssl/certs中,而基于 Red Hat 的发行版会将其包含在/etc/pki/tls/certs. 如果此目录存在,请设置 CA 路径参数:

curl_setopt($ch, CURLOPT_CAPATH, '/etc/ssl/certs');

或者,您可以引用单个 CA 证书文件。在您的项目中包含一个 cacert.pem 文件或将其安装在您的服务器上。从受信任的来源下载,例如 cacert.org。对于单个文件,不要设置 CAPATH,而只设置 CAINFO:

curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem');
于 2013-09-18T15:09:57.603 回答
1

为了扩展马特的答案,这两个 cURL 设置CURLOPT_CAPATHCURLOPT_CAINFO执行不同的功能和行为完全不同。

CURLOPT_CAINFO指单个文件,可以是证书捆绑包,也可以是不太常见的单个证书。该值可以(并且应该)在php.ini使用curl.cainfo指令时永久设置。

证书捆绑只是一堆连接在一起的证书,表明哪个 CA 的发行是受信任的。如果您没有,您的操作系统可能会提供一个可以安装的软件包。在 RHEL 上,可以yum install ca-certificates使用apt install ca-certificates. 如果您的操作系统不提供包,cURL 的制造商会提供一个下载链接,指向由 Mozilla 创建的包。

CURLOPT_CAPATH指持有个人证书的目录。如果您的请求的主机名与证书的公用名匹配,则 cURL 可以使用此目录中的证书。但是,重要的是要注意这不会自动发生。如果设置 CA 路径,则必须确保要在该目录中使用的任何证书都具有适当命名的符号链接(见下文。)


因此,将它们放在一起,我们得到以下典型设置。

将 cURL 永久指向系统捆绑包,使用如下内容php.ini

[curl]
; for RHEL
curl.cainfo=/etc/pki/tls/certs/ca-bundle.crt
; for Debian/Ubuntu
curl.cainfo=/etc/ssl/certs/ca-certificates.crt

这就是使用受信任的 CA 颁发的证书(即互联网上的几乎所有内容)连接到公共服务器所需要做的所有事情。如果这就是你所需要的,那么你就完成了。

对于其余情况,例如连接到使用公司 CA 颁发的证书的设备,请确保您已将相关证书复制到目录并正确设置符号链接名称:

#!/bin/bash
cd /path/to/my/certs/
for c in *.crt; do ln -s "$c" "$(openssl x509 -hash -noout -in "$c").0"; done

然后使用此 cURL 选项在您的代码中设置 CA 路径:

<?php
$ch = curl_init("https://some.device.internal");
curl_setopt($ch, CURLOPT_CAPATH, "/path/to/my/certs/");
$result = curl_init($ch);
于 2019-05-15T19:40:22.747 回答