Ruby中HTTPS自签名TLS证书验证及GET请求SSL验证报错排查
问题1:Ruby中验证自签名TLS证书的正确姿势
你遇到的certificate verify failed (self signed certificate in certificate chain)报错,大概率是踩了两个常见坑:要么证书路径配置错了,要么指定的证书不是信任链里的有效根证书。
解决步骤如下:
- 先确认证书有效性:确保你手里的
.pem文件是目标服务器的自签名证书(或者签发该服务器证书的自签名根CA证书),可以用openssl x509 -in /Users/me/Desktop/demp.pem -text命令查看证书内容,确认和服务器的证书信息匹配。 - 修正证书路径配置:你代码里
File.join(File.dirname(__FILE__), "/Users/me/Desktop/demp.pem")是错误的!File.dirname(__FILE__)会取当前脚本所在的目录,拼接绝对路径后会生成类似/your/script/folder/Users/me/Desktop/demp.pem的无效路径,直接写证书的完整绝对路径就行:http.ca_file = '/Users/me/Desktop/demp.pem' - 正确的完整配置示例:
require 'net/https' require 'uri' uri = URI.parse(ARGV[0] || 'https://example.com?password=my_password') http = Net::HTTP.new(uri.host, uri.port) if uri.scheme == "https" http.use_ssl = true # 开启严格验证(不建议关闭,除非是测试环境) http.verify_mode = OpenSSL::SSL::VERIFY_PEER # 直接指定正确的证书路径 http.ca_file = '/Users/me/Desktop/demp.pem' end http.start do http.request_get(uri.request_uri) do |res| print res.body end end
问题2:带密码参数的GET请求中使用SSL证书验证
密码参数属于URL的查询部分,和SSL验证本身没有冲突,你代码里的问题是用了uri.path——这个只会取URL的路径部分,密码参数会被丢掉!应该用uri.request_uri来包含完整的路径+查询参数。
另外,如果密码包含特殊字符(比如&、=),直接写在URL里会导致参数解析错误,建议用URI.encode_www_form来生成编码后的查询参数:
# 安全生成带密码参数的URI params = { password: 'my&special=password' } uri = URI.parse("https://example.com?#{URI.encode_www_form(params)}")
总结你代码里的两个关键问题
- 证书路径拼接错误:导致Ruby找不到你的自签名证书,直接使用绝对路径即可。
- 请求路径使用错误:
uri.path丢失了密码参数,换成uri.request_uri就能正确发送带参数的GET请求。
内容的提问来源于stack exchange,提问作者Ashima Sood
相关产品推荐
相关产品推荐

