以下脚本适用于 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/