BankID 和 CURL 错误 77 或 CURL 错误 60

BankID and CURL ERROR 77 or CURL ERROR 60

我花了几个小时试图让 cURL(在 PHP 中)与瑞典语 BankID service 和 运行 一起工作,导致以下两个证书错误:

CURL ERROR 60: SSL certificate problem: unable to get local issuer certificate

CURL ERROR 77: error setting certificate verify locations:
  CAfile: C:\test\bankid\bankid_test_server.pem
  CApath: C:\test\bankid\bankid_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_CAINFOCURLOPT_CAPATH 选项的各种变体,但我仍然遇到两个错误中的任何一个(当我尝试一些变体选项时,我得到一个,当我尝试一些其他变体我得到另一个错误)。

我按照 this SO question 中所述的使用 Firefox 导出服务器证书的建议获得了服务器证书。证书文件位于正确位置且可读。

原来问题出在证书文件本身的内容上。

首先,使用 Firefox 导出它不会为您提供正确的证书。它应该从 the BankID integrations guide 下载。在 Production environmentTest environment 部分的扩展 header Issuer of server certificate 下查看,并复制以

开头的实际证书字符串

-----BEGIN CERTIFICATE-----

并以

结尾

-----END CERTIFICATE-----

(包括起始行和结束行)。

其次,如果您只是将它按原样粘贴到文本文件中,那仍然不适用于 cURL。看来需要按某种方式格式化,更精确地分解为64个字符的长行。

您可以使用在线工具,例如 samltool.com - Format a X.509 certificate 来执行此操作。将您复制的文本粘贴到字段 X.509 cert 中,按 Format X.509 certificate,然后从字段 X.509 cert with header 中复制文本。将其粘贴到您服务器上的证书文件中(在我的例子中 C:\test\bankid\bankid_test_server.pem)。该文件现在应以

开头

-----BEGIN CERTIFICATE-----

后面是一堆 64 个字符的长行,并以

结尾

-----END CERTIFICATE-----

如果仍然无效,请确保证书文件的路径正确,PHP 可读,并且您复制了正确的 (production/test) 证书,具体取决于如果您正在调用测试或生产 URL。