Perl调用REST API遇Bad Certificate错误,证书链为空问题排查
问题:Perl LWP::UserAgent调用REST API时证书相关SSL握手失败
客户端错误信息
500 Can't connect to www.abc.com:44
客户端代码
#!/usr/bin/perl -w use LWP::UserAgent; my $client = LWP::UserAgent->new; # Load client certificate $client->ssl_opts( SSL_cert_file => 'ca-cert.pem', SSL_key_file => 'key.pem' ); # Verify server certificate $client->ssl_opts( SSL_verify_mode => SSL_VERIFY_PEER ); # Set up HTTPS request my $response = $client->get('https://exmaple.com/serviceNow/1.0.0?format=json'); if ($response->is_success) { print $response->decoded_content; } else { print $response->status_line; }
服务器端异常日志
核心异常:
javax.net.ssl.SSLHandshakeException: Empty server certificate chain at sun.security.ssl.Alert.createSSLException(Alert.java:131)" }
详细握手日志:
javax.net.ssl|FINE|1E|https-jsse-nio-8124-exec-3|2023-12-07 11:31:15.485 UTC|CertificateMessage.java:372|Consuming client Certificate handshake message ( "Certificates": <empty list> ) javax.net.ssl|SEVERE|1E|https-jsse-nio-8124-exec-3|2023-12-07 11:31:15.486 UTC|TransportContext.java:347|Fatal (BAD_CERTIFICATE): Empty server certificate chain
排查与解决方案
1. 修正基础配置错误
- 代码中域名拼写错误:
exmaple.com改为真实合法的目标域名 - 端口异常:错误信息中的
:44应为HTTPS默认端口:443,确认URL中的端口配置正确
2. 确保证书文件完整且路径正确
- 检查
ca-cert.pem和key.pem文件是否存在于脚本运行目录,路径无拼写错误 - 验证证书内容:
ca-cert.pem需要包含客户端证书+中间证书(若有)+根CA证书的完整链,顺序为客户端证书在前,中间证书次之,根CA最后。用以下命令检查证书内容:openssl x509 -in ca-cert.pem -text
3. 合并ssl_opts配置避免覆盖
将两次ssl_opts调用合并为一次,确保所有SSL配置生效:
$client->ssl_opts( SSL_cert_file => 'ca-cert.pem', SSL_key_file => 'key.pem', SSL_verify_mode => SSL_VERIFY_PEER );
4. 验证私钥与证书匹配性
用openssl命令确认私钥和证书属于同一对:
openssl x509 -noout -modulus -in ca-cert.pem | openssl md5 openssl rsa -noout -modulus -in key.pem | openssl md5
两个命令输出的MD5值必须完全一致,否则需更换匹配的私钥/证书。
5. 启用SSL调试模式定位问题
在代码开头添加SSL调试模块,输出握手过程细节:
use IO::Socket::SSL qw(debug3);
运行脚本后可查看SSL握手的每一步日志,精准定位证书加载失败的具体原因。
内容的提问来源于stack exchange,提问作者Alok
相关产品推荐
相关产品推荐

