错误信息
SSL operation failed with code 1. OpenSSL Error messages:
也可能输出为
- Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
PHP 把这条警告打印成两行:先是“SSL operation failed with code 1. OpenSSL Error messages:”,后面跟着一条或多条 OpenSSL 错误。基于 OpenSSL 1.1.1 的构建显示的则是“error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed”。
PHP streams (file_get_contents, fopen, stream_socket_client, SoapClient, mail libraries) — openssl stream wrapper
含义
PHP 流(file_get_contents、fopen、SoapClient、stream_socket_client,以及基于它们构建的邮件库或 FTP 库)的 TLS 握手失败了。代码 1 是 OpenSSL 的错误码 SSL_ERROR_SSL;真正的原因在下一行,最常见的是“error:0A000086:SSL routines::certificate verify failed”。随后 PHP 还会加上“Failed to enable crypto”和“Failed to open stream: operation failed”,它们是结果,而不是原因。
原因
服务器的 CA 不受信任
常见私有 CA 或代理的 CA,或者服务器没有发送中间证书。
PHP 流没有可用的 CA 证书包
常见在 OpenSSL 默认路径下没有证书包的系统上(Windows、精简镜像),openssl.cafile 没有设置。
协议或加密算法协商失败
偶见如果第二行是其他原因(“unsupported protocol”、“alert handshake failure”),说明服务器和 PHP 之间没有共同支持的 TLS 版本或加密算法。
修复方法
- 1.
查看后面那行 OpenSSL 错误
“certificate verify failed”指向信任问题或日期问题;协议错误则指向服务器的 TLS 配置。
text Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed <- trust/chain/date problem Warning: file_get_contents(): Failed to enable crypto <- consequence, not the cause - 2.
设置 openssl.cafile
PHP 流使用 openssl.cafile(或 openssl.capath),ext-curl 使用 curl.cainfo,所以两者都要设置。
ini ; php.ini — CA bundle for PHP streams (file_get_contents, SoapClient, stream_socket_client) openssl.cafile = "/etc/ssl/certs/ca-certificates.crt" - 3.
只为单个请求传入 CA
设置了 ssl.cafile 的流上下文可以信任私有 CA,而不会削弱其他连接的验证。
php // One request with a private CA; verification stays on $context = stream_context_create(['ssl' => [ 'cafile' => '/etc/ssl/private-ca/corp-root-ca.pem', 'verify_peer' => true, 'verify_peer_name' => true, ]]); $body = file_get_contents('https://api.example.com/', false, $context);