PHP 5.2.6集成OIDC时遭遇Unknown SSL protocol error问题求助
用PHP 5.2.6实现OIDC时,在fetchURL过程中遇到「Unknown SSL protocol error in connection」错误,相关代码如下:
curl_setopt($ch, CURLOPT_URL, $url); if (isset($this->certPath)){ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_CAINFO, $this->certPath); } else{ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); } curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $output = curl_exec($ch); if (curl_exec($ch) === false){ throw new OpenIDConnectioClientException('Curl error: ' . curl_error($ch)); }
已尝试以下操作但均无效:
- 设置IT提供的CA文件(cacert.pem)
- 将
CURLOPT_SSL_VERIFYPEER/CURLOPT_SSL_VERIFYHOST设为false - 指定不同的SSL版本(DEFAULT / TLSv1 / SSLv2, SSLv3, TLSv1_0, TLSv1_1, TLSv1_2)
- 开启
CURLOPT_VERBOSE未获取到有效详细信息
仅以下操作可获取目标服务响应:
- PHP CURL中将URL改为http而非https
- Windows curl 8.0.1添加
-k或--ssl_no_revoke参数 - Linux curl 7.68.0配置IT提供的cacert.pem
疑问:PHP CURL配置CA文件理论上应和Linux curl效果一致,为何不同系统结果不同?该如何解决?
版本信息:
- PHP 5.2.6 搭配 curl 7.16.0
- Windows curl 8.0.1 (Windows) libcurl/8.0.1 Schannel WinIDN
- Linux curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
不同系统结果差异的核心原因在于curl版本过旧+底层SSL库实现不同:
PHP环境的curl版本过于老旧:curl 7.16.0是2007年的版本,不支持TLS 1.1/1.2等现代协议,而当前OIDC服务基本都禁用了老旧的SSLv3/TLS1.0,直接导致SSL握手失败。同时该版本对CA证书的处理逻辑存在缺陷,证书链不完整、路径解析错误都可能触发报错。
SSL库实现差异:
- Windows curl 8.0.1基于Schannel(Windows系统自带SSL库),
--ssl_no_revoke参数可跳过证书吊销检查;而旧版PHP curl可能强制执行吊销检查,但无法正确获取CRL/OCSP信息,进而报错。 - Linux curl 7.68.0基于OpenSSL 1.1.1f,支持现代TLS协议,对CA证书的验证流程更完善,因此配置证书后能正常工作。
- Windows curl 8.0.1基于Schannel(Windows系统自带SSL库),
Windows路径兼容问题:旧版PHP curl在Windows环境下处理
CURLOPT_CAINFO路径时,对反斜杠的转义处理存在问题,可能导致证书文件无法被正确读取,看似配置了CA文件实际未生效。
优先建议升级PHP和curl版本(PHP 5.2已停止维护,存在极大安全风险),若无法升级,可尝试以下方案:
指定兼容的SSL版本常量
旧版curl不支持CURL_SSLVERSION_TLSv1_0这类新常量,需使用旧版兼容常量,添加代码:curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);注意:此方案生效的前提是目标服务仍支持TLS1.0。
修正CA文件路径格式
在Windows环境下,将路径转换为正斜杠或双反斜杠格式,避免路径解析失败:curl_setopt($ch, CURLOPT_CAINFO, str_replace('\\', '/', $this->certPath));同时确认cacert.pem包含完整的证书链(根CA+中间CA),旧版curl对不完整证书链兼容性极差。
临时跳过SSL检查(仅应急,不推荐)
除关闭VERIFYPEER和VERIFYHOST外,添加加密套件配置尝试绕过部分检查:curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'ALL');替换PHP的curl扩展
寻找支持PHP 5.2.6的较新版本curl扩展(如7.30+),替换系统自带的旧版curl库,提升协议兼容性。使用代理中转请求
搭建简单中转服务(如用Linux curl编写脚本),PHP通过HTTP请求代理,由代理完成HTTPS握手,避开旧版curl的SSL缺陷。
内容的提问来源于stack exchange,提问作者Nick Lin

