带有 ca 认证的 Ruby https 在与 curl 一起使用时不起作用

GPi*_*Pif 5 ruby ssl certificate ssl-certificate net-http

在 ruby​​ 中,我尝试使用自动签名证书与本地设置的 nginx 服务器建立 ssl 连接。我的代码是:

require "net/http"
require "net/https"
require "openssl"
require "uri"
require "pp"

request = Net::HTTP::Get.new("/")
response = Net::HTTP.start(
  "localhost",
  443,
  {
    :use_ssl => true,
    :key => OpenSSL::PKey::RSA.new(File.read("/home/gg/crt/client.key")),
    :cert => OpenSSL::X509::Certificate.new(File.read("/home/gg/crt/client.crt")),
    :ca_file => "/home/gg/crt/ca.pem",
    :verify_mode => OpenSSL::SSL::VERIFY_PEER,
    :verify_depth => 5,
  }
) do |http|
      http.request(request)
end
puts response.inspect
puts response.body
Run Code Online (Sandbox Code Playgroud)

当我运行它时它返回

/home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:923:in `connect': SSL_connect returned=1 errno=0 state=error: certificate verify failed (OpenSSL::SSL::SSLError)
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:923:in `block in connect'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/timeout.rb:74:in `timeout'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:923:in `connect'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:863:in `do_start'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:852:in `start'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:583:in `start'
    from testso.rb:8:in `<main>'
Run Code Online (Sandbox Code Playgroud)

但如果我用curl运行它,我会得到正确的结果:

curl https://localhost --key crt/client.key --cert crt/client.crt --cacert crt/ca.pem
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

GPi*_*Pif 1

我感觉自己很蠢,但还是找到了问题所在。

生成不同的证书时,我将一些字段留空。看来 openssl 检测到此证书“看起来”是自动签名的。

因此,如果我们使用 OpenSSL::SSL::VERIFY_PEER 连接失败

因此,为了确保使用 CA 正确生成证书,您可以执行以下操作:( openssl verify -CAfile ca.crt server.crt 以及与 client.crt 相同的命令)

如果我们得到

error 18 at 0 depth lookup:self signed certificate
OK
Run Code Online (Sandbox Code Playgroud)

证书被检测为自动签名并且失败

如果我们得到

 Signature ok
Run Code Online (Sandbox Code Playgroud)

应该有效