简体   繁体   中英

How to verify server SSL certificate?

I am a newbie on SSL concept, I am trying to connect to API which has x509 mutual auth using HTTParty.

I got client cert, client key and server cert (all are pem files).

I got it working with client cert and key and with verify: false .

Now next step is how to verify server cert also?

HTTParty documentation link 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

Call to service client

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

Edit:

HTTParty is not a hard requirement so solution with any http client would work for me.

If I remove verify: false I get below error.

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

By default, the TLS protocol only proves the identity of the server to the client, leaving the authentication of the client to the server to the application layer, eg, HTTP Basic authentication.

Mutual TLS authentication refers to the client and server authenticating each other at the same time. It can be used as an alternative to HTTP Basic authentication. It's also often called certificate-based authentication.

Looks like you're getting this error (but works with verify: false ) because the server certificate isn't trusted. Is it self-signed? Or perhaps the certificate authority (CA) who issued the certificate isn't trusted in your system.

HTTParty is built on top of Net::HTTP , which uses OpenSSL , which gets the trusted CA certificates from the system, eg /etc/ssl/cert.pem . Although you could override the SSL_CERT_FILE environment variable, I don't think it's a good idea because it might impact other parts of your application. A better solution would be to pass the CA certificates to HTTParty only.

I've never used HTTParty, so bear with me. But taking a quick look at the code and assuming you're using the default ConnectionAdapter , looks like you need to define both pem and ssl_ca_file options, which will define the client and CA certificate files, respectively. Also note that by doing it so, 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

I don't think it's related to your issue, but if your client key has a passphrase, make sure to pass it on pem(pem_contents, password) .

HTH. Best.

Try as you I suppose you are using ssl certificate that you want to verify. Also it's quite easier in RestClient, I am adding snippet at the end.

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 solution:

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

This should solve the problem:

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

Ref: https://github.com/rest-client/rest-client

Use " OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE"

In your code , maybe look like to:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM