首页 > 解决方案 > 如何验证服务器 SSL 证书?

问题描述

我是 SSL 概念的新手,我正在尝试使用 HTTParty 连接到具有 x509 相互身份验证的 API。

我得到了客户端证书、客户端密钥和服务器证书(都是 pem 文件)。

我让它与客户端证书和密钥以及verify: false.

现在下一步是如何验证服务器证书呢?

HTTParty 文档链接https://github.com/jnunemaker/httparty/tree/master/docs#working-with-ssl

class ServiceClient
  include HTTParty
  DEFAULT_HEADERS = {
    'Content-Type' => 'application/json'
  }.freeze
  base_uri 'https://example.com'
  pem File.read("#{File.expand_path('.')}/path/to/certs/cert.pem")

  def self.iframe_url(**payload)
    post(
     '/test/create',
     body: payload.to_json,
     headers: DEFAULT_HEADERS,
     verify: false
    )
  end
end

致电服务客户

payload = {user_id: "100", account_id: "1234"} 
ServiceClient.iframe_url(payload)

编辑:

HTTParty 不是硬性要求,因此任何 http 客户端的解决方案都对我有用。

如果我删除verify: false我得到以下错误。

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed

标签: ruby-on-railsrubyhttpclienthttparty

解决方案


默认情况下,TLS 协议只向客户端证明服务器的身份,将客户端的身份验证留给服务器到应用层,例如 HTTP Basic 身份验证。

双向 TLS 认证是指客户端和服务器同时相互认证。它可以用作 HTTP Basic 身份验证的替代方案。它通常也称为基于证书的身份验证。

看起来您收到此错误(但适用于verify: false),因为服务器证书不受信任。是自签吗?或者,颁发证书的证书颁发机构 (CA) 在您的系统中可能不受信任。

HTTParty 建立在 之上Net::HTTP,它使用OpenSSL,它从系统中获取受信任的 CA 证书,例如/etc/ssl/cert.pem. 尽管您可以覆盖SSL_CERT_FILE环境变量,但我认为这不是一个好主意,因为它可能会影响应用程序的其他部分。更好的解决方案是将 CA 证书仅传递给 HTTParty。

我从未使用过 HTTParty,所​​以请耐心等待。但是快速查看 代码 并假设您使用的是 default ConnectionAdapter,看起来您需要同时定义pemssl_ca_file选项,这将分别定义客户端和 CA 证书文件。另请注意,这样做会打开证书验证

class ServiceClient
  include HTTParty
  pem "path/to/client_cert_and_key.pem"
  ssl_ca_file "path/to/ca_certificates.pem"
end

我认为这与您的问题无关,但如果您的客户端密钥有密码,请确保将其传递给pem(pem_contents, password).

HTH。最好的。


推荐阅读