Can't connect with SSL certificate - ruby

I've pfx sectificate, with which I have to log into a specific URL to send and receive data. It's self-signed certificate.
Made pem files:
openssl pkcs12 -in client_ssl.pfx -out client_smsgate-in.pem -clcerts
openssl pkcs12 -in client_ssl.pfx -out ca_client_smsgate-in.pem -cacerts
Try connections:
require "net/https"
require "uri"
uri = URI.parse("myurl.ru")
pem = File.read("client_smsgate-in.pem")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.ca_file = File.read("ca_client_smsgate-in.pem")
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.cert = OpenSSL::X509::Certificate.new(pem)
http.key = OpenSSL::PKey::RSA.new(pem, 'pass')
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
I've error:
lib/ruby/2.2.0/net/http.rb:923:in 'connect': SSL_connect returned=1 errno=0 state=unknown state: certificate verify failed (OpenSSL::SSL::SSLError)
If check OpenSSL::SSL::VERIFY_NONE, it works. tell me what's wrong, because I have CA certificates to him?

Related

Using self signed certificate

I used this to generate .crt and .key files:
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout example.key -out example.crt -subj "/CN=example.com" -addext "subjectAltName=DNS:example.com,DNS:www.example.net,IP:127.0.0.1"
I have this node.js code:
var https = require('https');
var fs = require('fs');
var privateKey = fs.readFileSync('sslcert/example.key', 'utf8');
var certificate = fs.readFileSync('sslcert/example.crt', 'utf8');
var credentials = { key: privateKey, cert: certificate };
var express = require('express');
var app = express();
httpsServer.listen(8443);
I could use Postman and get the response using the 8443 port.
When I use the browser, I get this error:
127.0.0.1:8443 uses an invalid security certificate.
The certificate does not come from a trusted source.
I installed the .crt file on my Windows machine. I also tried to import the .crt file to Firefox. When I try to import it under "Your certificates" I get this error:
This personal certificate can’t be installed because you do not own the corresponding private key which was created when the certificate was requested.
When I import it to "Authorities" it works. Why? My self signed certificate acts as a CA?

Https response time in ruby

I'm trying to get webservice response time using ruby. My code
require 'net/http'
require 'benchmark'
require 'uri'
puts time = Benchmark.realtime = {Net::HTTP.get_response(URI.parse("http://webservice"))}
It works fine but when I'm trying to get response time of https based url I get an error
'connect_nonblock': SSL_connect returned=1 errno=0 state=error: certificate verify faule
Is any way to fix this?
You should make request with enabled ssl:
uri = URI('https://secure.example.com/some_path?query=string')
Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
request = Net::HTTP::Get.new uri
response = http.request request # Net::HTTPResponse object
end

Verify self-signed TLS certificate for HTTPS in Ruby

How do I use SSL certificate verification in GET Request in RUBY (using password parameter in URL)? ->
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=File.join(File.dirname(__FILE__),
"/Users/me/Desktop/demp.pem")
end
http.start do
http.request_get(uri.path) do |res|
print res.body
end
end
--> output
SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate in certificate chain) (OpenSSL::SSL::SSLError)
This worked for me.
require 'net/http'
require 'net/https'
require 'openssl'
require 'uri'
require 'json'
ContentURI = URI.parse("example.com")
#cert_raw = File.read('cert.pem')
TestDataPath = '.'
req = Net::HTTP::Get.new(ContentURI.path)
https = Net::HTTP.new(ContentURI.host, ContentURI.port)
https.use_ssl = true
https.cert = OpenSSL::X509::Certificate.new(#cert_raw)
https.key = OpenSSL::PKey::RSA.new(#cert_raw)
https.verify_mode = OpenSSL::SSL::VERIFY_PEER
resp = https.start { |cx| cx.request(req) }
p resp
p resp.body

Apple Pay on the web merchant session in ruby

I can't seem to be able to get the merchant session validation working with Ruby. Tried HTTParty and RestClient and I'm getting:
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv3 read finished A: sslv3 alert certificate expired):
I tried the same certificate with this node server example, https://github.com/tomdale/apple-pay-merchant-session-server, and it worked fine, so it must be something in my ruby code.
Has anyone managed to get this working?
I was having the same problem. With the help of the example you referenced and the implementation at https://github.com/norfolkmustard/ApplePayJS (see also the discussion about the implementation at https://forums.developer.apple.com/thread/51580) I was able to get it working.
The key for me was passing in the correct certificate (the Apple Pay Merchant Identity certificate) just as Apple provides it and getting the cert key like so:
Once you have your Merchant ID (session) certificate from Apple, import that into keychain.app on your Mac by double-clicking it, right click on the cert in keychain and export the combined private-key and cert as a .p12 file then, in terminal:-
openssl pkcs12 -in your_merchant_identity_cert_name.p12 -out ApplePay.key.pem -nocerts -nodes
After adding the Apple Pay Merchant Identification cert from Apple and the contents of the ApplePay.key.pem file to an environment variable I was able to construct the following request using Ruby's Net::HTTP class...
class YourControllerName < ApplicationController
def apple_pay_validation
respond_to do |format|
format.json { render json: start_apple_session(params[:url]) } if params[:url].include?('apple.com')
end
end
private
def start_apple_session(url)
uri = URI.parse(url) # the url from event.validationURL
data = {'merchantIdentifier' => "merchant.com.your_site_name", 'domainName' => "your_doamin", 'displayName' => "your_company_name"}
pem = File.read('path/to/your/merchant_id.cer')
key = ENV['APPLE_PAY_MERCHANT_ID_ KEY']
passphrase = 'passphrase set up when exporting certificate in keychain' # Should be an environment variable
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.ssl_version = :TLSv1_2
http.ciphers = ['ECDHE-RSA-AES128-GCM-SHA256']
http.cert = OpenSSL::X509::Certificate.new(pem)
http.key = OpenSSL::PKey::RSA.new(key, passphrase)
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
request = Net::HTTP::Post.new(uri.request_uri, 'Content-Type' => 'application/json')
request.body = data.to_json
response = http.request(request)
response.body
end
end
This was called from my performValidation function (modified from the ApplePayJS repo listed above) which looks like this..
performValidation = (valURL) ->
new Promise((resolve, reject) ->
xhr = new XMLHttpRequest
xhr.open 'GET', '/your_controller_name/apple_pay_validation?url=' + valURL
xhr.onerror = reject
xhr.onload = ->
data = JSON.parse(#responseText)
resolve data
xhr.send()
)
Hopefully that helps save someone some time and gray hairs!

How to connect to an https server with an invalid certificate using the latest versions of Ruby

Consider the following code:
require 'net/https'
uri = URI.parse("https://host/index.html")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.path)
response = http.request(request)
where https://host/index.html is a valid address with an invalid certificate on the server.
On older versions of ruby (specifically 1.8.7-p334 and 1.9.2-p180) this code works fine. On all recent versions (1.8.7-p352, 1.9.2-p290 and 1.9.3-p0) it throws the following exception:
OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=unknown state
on the last line.
Changing verify_mode to OpenSSL::SSL::VERIFY_PEER gives exactly the error suggesting it is attempting to verify the certificate in spite of the setting.
How can I convince ruby to ignore the invalid certificate and connect?
uri = URI("https://host/index.html")
req = Net::HTTP::Get.new(uri.path)
res = Net::HTTP.start(
uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |https|
https.request(req)
end
require 'nokogiri'
require 'open-uri'
require 'net/https'
#doc = Nokogiri::HTML(open(my_url, :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE))

Resources