我花了几个小时试图让cURL(用PHP(与瑞典银行ID服务一起使用,但遇到了以下两个证书错误:
CURL ERROR 60: SSL certificate problem: unable to get local issuer certificate
CURL ERROR 77: error setting certificate verify locations:
CAfile: C:testbankidbankid_test_server.pem
CApath: C:testbankidbankid_test_server.pem
我用来初始化cURL的代码如下:
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd().DIRECTORY_SEPARATOR.$bankidServerCertFile);
curl_setopt($ch, CURLOPT_CAPATH, getcwd().DIRECTORY_SEPARATOR.$bankidServerCertFile);
curl_setopt($ch, CURLOPT_SSLCERT, $clientCertFile);
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $clientCertPass);
curl_setopt($ch, CURLOPT_SSLKEY, $clientCertKeyFile);
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $clientCertKeyPass);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
我尝试过CURLOPT_CAINFO
和CURLOPT_CAPATH
选项的各种变体,但仍然会出现这两个错误中的任何一个(当我尝试某些变体时,我会得到一个,当我尝试其他变体时,会得到另一个错误(。
我按照建议使用Firefox导出服务器证书,正如这个SO问题中所描述的那样。证书文件位于正确的位置并且可读。
原来问题出在证书文件本身的内容上。
首先,使用Firefox导出它并不能给你正确的证书。它应该从BankID集成指南中下载。在Production environment
或Test environment
部分的扩展标头Issuer of server certificate
下查找,并复制以开头的实际证书字符串
-----BEGIN CERTIFICATE-----
以结束
-----END CERTIFICATE-----
(包括起始线和结束线(。
其次,如果你只是将cURL原样粘贴到文本文件中,这对cURL仍然不起作用。它似乎需要以某种方式进行格式化,更准确地说,需要分解为64个字符的长行。
您可以使用在线工具,如samltool.com-格式化X.509证书来执行此操作。将复制的文本粘贴到字段X.509 cert
,按Format X.509 certificate
,然后从字段X.509 cert with header
复制文本。将其粘贴到服务器上的证书文件中(在我的案例中为C:testbankidbankid_test_server.pem
(。文件现在应该以开头
-----BEGIN CERTIFICATE-----
然后是一组64个字符的长行,并以结尾
-----END CERTIFICATE-----
如果它仍然不起作用,请确保证书文件的路径正确,PHP可读,并且您复制了正确的(生产/测试(证书,这取决于您调用的是测试URL还是生产URL。