如何验证服务器SSL证书?X509双向认证HTTP客户端配置问题
解决X509双向认证下的服务器证书验证问题
嘿,我来帮你搞定这个事儿!你现在的情况是关掉verify: false能正常连,但一开验证就报certificate verify failed,核心原因很简单:Ruby的SSL默认信任链里没有你拿到的服务器证书(毕竟它大概率是自签名或者私有CA签发的),所以得手动告诉客户端要信任这个服务器证书。
下面给你几个常用HTTP客户端的解决方案,HTTParty和其他工具的都有:
一、HTTParty 解决方案
直接在请求里指定客户端证书、密钥,同时把服务器证书作为信任的CA文件传入,别再用verify: false了:
require 'httparty' # 加载客户端证书和密钥 client_cert = OpenSSL::X509::Certificate.new(File.read('client_cert.pem')) client_key = OpenSSL::PKey::RSA.new(File.read('client_key.pem')) # 发起请求,指定信任的服务器证书 response = HTTParty.get('https://your-api-domain.com/endpoint', ssl_cert: client_cert, ssl_key: client_key, ssl_ca_file: 'server_cert.pem' # 关键:用这个文件验证服务器身份 ) puts response.body
如果你的服务器证书是链式证书(比如包含根CA、中间CA和服务器证书),把所有证书内容合并到同一个PEM文件里,再传给ssl_ca_file就行。
二、Net::HTTP 解决方案(Ruby原生)
如果不想用HTTParty,Ruby原生的Net::HTTP也能轻松搞定:
require 'net/http' require 'openssl' uri = URI('https://your-api-domain.com/endpoint') http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true # 设置客户端凭证 http.cert = OpenSSL::X509::Certificate.new(File.read('client_cert.pem')) http.key = OpenSSL::PKey::RSA.new(File.read('client_key.pem')) # 开启服务器证书验证,并指定信任的证书 http.ca_file = 'server_cert.pem' http.verify_mode = OpenSSL::SSL::VERIFY_PEER # 这是默认值,但明确写出来更清晰 # 发起请求 response = http.get(uri.request_uri) puts response.body
三、Faraday 解决方案(灵活的HTTP客户端)
要是你用Faraday,配置方式也类似:
require 'faraday' require 'openssl' conn = Faraday.new(url: 'https://your-api-domain.com') do |faraday| # 配置客户端证书和密钥 faraday.ssl.cert = OpenSSL::X509::Certificate.new(File.read('client_cert.pem')) faraday.ssl.key = OpenSSL::PKey::RSA.new(File.read('client_key.pem')) # 指定信任的服务器证书 faraday.ssl.ca_file = 'server_cert.pem' # 使用默认适配器 faraday.adapter Faraday.default_adapter end response = conn.get('/endpoint') puts response.body
几个注意事项
- 如果客户端密钥有密码,加载的时候要传入密码:
OpenSSL::PKey::RSA.new(File.read('client_key.pem'), 'your-key-password') - 确保服务器证书的PEM格式正确,不要有多余的换行或乱码
- 检查服务器域名和证书里的**CN(通用名称)或SAN(主题备用名称)**是否匹配,不匹配的话也会触发验证失败,这种情况要么更新证书,要么特殊处理(但不推荐,安全性会下降)
内容的提问来源于stack exchange,提问作者pramodtech
相关产品推荐
相关产品推荐

