PHP cURL报错error 58:本地SSL证书问题排查咨询
问题描述
开发需使用双向证书的信用卡支付集成项目时,配置证书相关参数后运行代码抛出cURL error 58 - Problem with the local SSL certificate错误。
初始证书配置如下:
$certificate = array( 'private_key_path' => '/usr/www/users/2619100.key', 'public_key_path' => '/usr/www/users/2619100.pem', 'password' => '4545xss' );
对应业务代码:
$params = array( 'device_fingerprint' => array( 'ip_address' => $_SERVER['REMOTE_ADDR'], 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ) ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $api_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Authorization: Bearer '. $api_key, 'Content-Type: application/json', 'gateway-entity-id: ' . $this->gateway_entity_id, 'client-request-id: ' . uniqid() )); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params)); curl_setopt($ch, CURLOPT_VERBOSE, 1); if($this->request_type == 'VALIDATION' || $this->request_type == 'PRODUCTION') { curl_setopt($ch, CURLOPT_SSLKEY, $this->certificate['private_key_path']); curl_setopt($ch, CURLOPT_SSLCERT, $this->certificate['public_key_path']); curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $this->certificate['password']); } curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); $data = json_decode(curl_exec($ch), true); if($errno = curl_errno($ch)) { $error_message = curl_strerror($errno); throw new Exception('cURL error ' . $errno . ' - ' . $error_message); } $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
排查与解决步骤
按优先级从高到低逐一排查:
- 检查证书文件路径与权限
cURL 报58错误最常见的原因是进程读不到证书文件:- 执行
ls -l /usr/www/users/2619100.key /usr/www/users/2619100.pem确认两个文件真实存在,路径拼写完全正确,必须使用绝对路径,不要用相对路径。 - 确认运行PHP的进程用户(通常是www-data、nginx、apache用户)对两个文件有可读权限,可执行
chmod 644 /usr/www/users/2619100.key /usr/www/users/2619100.pem设置权限,不要设置777权限,部分支付网关会拒绝权限过于开放的证书。 - 如果PHP开启了
open_basedir限制,要确认两个证书文件都在open_basedir允许的访问目录范围内,否则进程无权读取。
- 执行
- 校验证书、私钥的合法性与匹配度
文件存在但内容损坏、密码错误、公私钥不匹配也会触发该错误,用openssl命令本地校验:- 校验私钥合法性和密码是否正确:执行
openssl rsa -in /usr/www/users/2619100.key -check -passin pass:4545xss,命令报错则说明私钥损坏或者密码配置错误。 - 校验公钥证书合法性:执行
openssl x509 -in /usr/www/users/2619100.pem -text -noout,命令报错则说明pem证书损坏、格式不符合要求。 - 校验公私钥是否匹配:分别执行以下两条命令,输出的MD5值必须完全一致,不一致说明私钥和证书不是配对的。
openssl rsa -in /usr/www/users/2619100.key -modulus -noout -passin pass:4545xss | openssl md5 openssl x509 -in /usr/www/users/2619100.pem -modulus -noout | openssl md5 - 如果你的证书是PFX/P12格式(Windows平台导出常见),需要先转成PEM格式才能被cURL识别,转换后分别提取私钥和公钥证书内容存为对应文件。
- 校验私钥合法性和密码是否正确:执行
- 修正cURL SSL参数配置
当前代码存在参数配置遗漏:CURLOPT_SSLCERTPASSWD仅用于设置公钥证书的密码,如果你的私钥单独设置了密码,需要额外增加配置curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $this->certificate['password']);,两个密码参数不要搞混。
- 抓取详细Verbose日志定位根因
已经开启CURLOPT_VERBOSE的前提下,可以把详细日志输出到临时流查看具体报错点,参考代码:
常见日志对应问题:$verboseLog = fopen('php://temp', 'w+'); curl_setopt($ch, CURLOPT_STDERR, $verboseLog); // 执行curl_exec、错误捕获逻辑 rewind($verboseLog); $logContent = stream_get_contents($verboseLog); fclose($verboseLog); // 将$logContent写入业务日志,即可看到明确错误原因- 出现
could not load PEM client certificate, OpenSSL error error:02001003:system library:fopen:No such process:文件不存在/路径错误/权限不足 - 出现
could not load PEM client certificate, OpenSSL error error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib:密码错误/私钥损坏/公私钥不匹配
- 出现
内容的提问来源于stack exchange,提问作者TSCAmerica.com
相关产品推荐
相关产品推荐

