我们的网站最近从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
cURL版本:7.21.6
SSL版本:OpenSSL / 1.0.0e
答案 0 :(得分:7)
不要像其他人经常建议的那样关闭对等和主机验证。这是解决实际问题的不安全方法。这些功能存在的原因很充分:因此您可以通过第三方信任您所连接的系统是您期望的系统。
首先查找您的操作系统是否包含证书目录。通常会包括证书颁发机构。例如,在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');
答案 1 :(得分:0)
要扩展Matt的答案,两个cURL设置CURLOPT_CAPATH
和CURLOPT_CAINFO
执行不同的功能,并且行为也完全不同。
CURLOPT_CAINFO
是指单个文件,既可以是证书捆绑包,也可以是单个证书(较不常见)。可以(并且应该)使用curl.cainfo
directive在php.ini
中永久设置该值。
证书捆绑包只是一堆串联的证书,表明将信任哪些CA的发行。如果您没有,则您的操作系统可能会提供可以安装的软件包。在RHEL上,可以使用yum install ca-certificates
完成,而Debian / Ubuntu使用apt install ca-certificates
。如果您的操作系统未提供软件包,则cURL的创建者会向由Mozilla创建的捆绑包提供a download link。
CURLOPT_CAPATH
是指保存单个证书的目录。如果您的请求的主机名与证书的通用名称匹配,则cURL可以使用此目录中的证书。但是,请务必注意this will not happen automatically 。如果设置了CA路径,则必须确保要在该目录中使用的所有证书都具有适当命名的符号链接(请参见下文)。
因此,将它们放在一起,我们得到以下典型设置。
使用php.ini
中的以下内容将cURL永久指向系统捆绑包:
[curl]
; for RHEL
curl.cainfo=/etc/pki/tls/certs/ca-bundle.crt
; for Debian/Ubuntu
curl.cainfo=/etc/ssl/certs/ca-certificates.crt
这是使用受信任的CA颁发的证书连接到公用服务器所要做的全部工作,即Internet上几乎所有内容。如果您只需要这些,就可以完成。
对于其余情况,例如连接到使用由公司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);
答案 2 :(得分:-1)
您需要将CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST设置为faslse或0.
curl_setopt($ ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ ch,CURLOPT_SSL_VERIFYHOST,FALSE);
aslo你需要确保yu将CURLOPT_URL设置为'https:// ...'
卡尔