php - cURL:CURLOPT_CAPATH 包含正确的证书但不起作用

标签 php ssl curl

以下脚本适用于 PHP 5.6.23:

$options = [
    CURLOPT_POST => 1,
    CURLOPT_URL => 'https://uat.dwolla.com/oauth/rest/offsitegateway/checkouts',
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_POSTFIELDS => json_encode(['name'=>'value']),
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_CAINFO => '/path/to/certs/GoDaddyRootCertificateAuthority-G2.crt',
];
$ch = curl_init();

curl_setopt_array($ch, $options);
if( ! $result = curl_exec($ch)) $err = curl_error($ch);
else $err = null;

curl_close($ch);

if($err) echo $err;
else print_r(json_decode($result,true));

我从 Dwolla 的支付 API 得到了预期的响应。为了使我的脚本更具动态性,我尝试将其更改为引用托管我希望 cURL 信任的证书的目录。所以我将最后一个选项 (CURLOPT_CAINFO) 更改为:

CURLOPT_CAPATH => '/path/to/certs'

然而,这会破坏脚本并且不会建立任何连接;错误是:

SSL certificate problem: unable to get local issuer certificate

我知道目录是正确的并且证书文件是有效的,因为原始脚本引用了同一目录中的证书。我希望 cURL 扫描目录中的文件并找到它需要的证书,但这并没有发生。这是为什么?

最佳答案

如果您只是将 CApath 指向某个目录并将证书放入该目录,这是行不通的。为了高效地找到正确的 CA 证书,此目录中的文件需要具有从证书主题派生的名称。例如,您可能会在 /etc/ssl/certs 中找到以下内容:

   ff783690.0 -> UTN_USERFirst_Hardware_Root_CA.pem
   ff588423.0 -> ComSign_CA.pem
   ...

此处的文件名基于证书主题的哈希值并指向真实证书。有关如何创建必要文件名的信息,请参阅 How to calculate the hash value used by CA file names .

另见 man page for openssl verify :

-CApath directory
A directory of trusted certificates. The certificates should have names of the form: hash.0 or have symbolic links to them of this form ("hash" is the hashed certificate subject name: see the -hash option of the x509 utility). Under Unix the c_rehash script will automatically create symbolic links to a directory of certificates.

关于php - cURL:CURLOPT_CAPATH 包含正确的证书但不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39174558/

相关文章:

ruby-on-rails-3 - Rails 3.2、activeresource 和证书认证

php - 使用 REST API 的 PayPal 订单摘要 - - cURL 或 PHP

node.js - 使用 Node 请求 OAuth 凭据

php - 在 phpunit 中运行一个文件或 map

javascript - Symfony 表单 AJAX 返回空对象

php - 使用 PHP 中的 POST 数据从 ASP.net 抓取数据

ssl - CSR 的数字签名是如何生成的?

Android SSL 证书固定

Java:发送POSTcurl命令在slack中发送消息

php - 获取时差