如何验证服务器SSL证书?

时间:2018-05-24 12:57:30

标签: ruby-on-rails ruby httpclient httparty

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

我获得了客户端证书,客户端密钥和服务器证书(所有都是pem文件)。

我使用客户端证书和密钥以及.gitignore

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

HTTParty文档链接documentation

verify: false

致电服务客户

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

修改

HTTParty不是一个硬性要求,所以任何http客户端的解决方案都适合我。

如果我删除payload = {user_id: "100", account_id: "1234"} ServiceClient.iframe_url(payload) ,我会收到以下错误。

verify: false

4 个答案:

答案 0 :(得分:3)

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

相互TLS身份验证是指客户端和服务器对每个身份验证进行身份验证 其他在同一时间。它可以用作HTTP Basic的替代方案 认证。它通常也称为基于证书的身份验证。

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

HTTParty构建于Net::HTTP之上,使用OpenSSL获取。{1}} 来自系统的可信CA证书,例如/etc/ssl/cert.pem。虽然你 可以覆盖SSL_CERT_FILE环境变量,我不认为它是一个 好主意,因为它可能会影响您应用程序的其他部分。一个更好的 解决方案是将CA证书仅传递给HTTParty。

我从未使用过HTTParty,所​​以请耐心等待。但快速浏览一下 code 并假设您使用的是默认ConnectionAdapter,看起来就像您需要的那样 定义pemssl_ca_file选项,它们将定义客户端 和CA证书文件。另请注意,通过这样做,it will turn certificate verification on

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。最好的。

答案 1 :(得分:1)

尝试我想您正在使用要验证的ssl证书。在RestClient中它也相当容易,我在最后添加了片段。

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


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

Rest Client解决方案:

client = RestClient::Resource.new('https://example.com/',
                              :ssl_client_cert => p12.certificate,
                              :ssl_client_key => p12.key,
                              :verify_ssl => OpenSSL::SSL::VERIFY_NONE)

答案 2 :(得分:1)

这应该可以解决问题:

RestClient::Resource.new(
  'https://example.com',
  :ssl_client_cert  =>  OpenSSL::X509::Certificate.new(File.read("cert.pem")),
  :ssl_client_key   =>  OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any"),
  :ssl_ca_file      =>  "ca_certificate.pem",
  :verify_ssl       =>  OpenSSL::SSL::VERIFY_PEER
).get

参考:https://github.com/rest-client/rest-client

答案 3 :(得分:-1)

使用“OpenSSL :: SSL :: VERIFY_PEER = OpenSSL :: SSL :: VERIFY_NONE”

在您的代码中,可能看起来像:

    class ServiceClient
      include HTTParty
      OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
      {...your code...}
    end