以下脚本适用于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证书问题:无法获得本地颁发者证书
我知道目录是正确的,并且证书文件是有效的,因为原始脚本引用了同一目录中的证书。我希望cURL
扫描目录中的文件并找到它需要的证书,但这不会发生。这是为什么?
答案 0 :(得分:4)
如果您只是将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目录
可信证书的目录。证书应具有以下形式的名称:hash.0或具有此表单的符号链接(" hash"是散列证书主题名称:请参阅x509实用程序的-hash选项)。在Unix下,c_rehash脚本将自动创建指向证书目录的符号链接。