繁体   English   中英

OpenSSL::SSL::SSLError: Ruby 客户端的服务器 ca 证书在使用 curl 时不起作用

[英]OpenSSL::SSL::SSLError: Ruby client's server ca certificate does not work while it worked with curl

我从客户那里获得了与他们的 VPN 连接的证书,但是当它与 curl 命令一起使用时,它不适用于 ruby​​ 代码。 卷曲命令如下:

curl --cacert cert.cer -d '{"acb": 123 }' -H 'Content-Type: application/json' 'https://demo.com'

在 ruby​​ 中,我正在尝试执行以下操作来连接提供给我们进行交易的客户端 API。

require 'net/http'
require 'json'
require 'uri'

full_url = "https://demo.com"
uri = URI.parse(full_url)

data = { "acb": 123 }
headers = { 'Content-Type' => "application/json" }

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

raw = File.read("path_to_the_certificate")
http.cert = OpenSSL::X509::Certificate.new(raw)

request = Net::HTTP::Post.new(uri.request_uri, headers)
request.body = data.to_json

response = http.request(request)

puts response.code
puts response.body

我们还尝试如下传递我们的服务器证书,但这也不起作用

http.ca_path='/etc/pki/tls/certs'
http.ca_file='/etc/pki/tls/certs/cert.cer'
http.cert = OpenSSL::X509::Certificate.new(File.read("/path/client.crt"))
http.key = OpenSSL::PKey::RSA.new(File.read("/path/client.key"))

在出现以下错误时

OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate))

我认为他们的自签名证书有问题。 验证失败。 但是,您可以手动禁用它

http.verify_mode = OpenSSL::SSL::VERIFY_NONE

验证模式[RW]

在 SSL/TLS 会话开始时为服务器证书验证设置标志​​。

OpenSSL::SSL::VERIFY_NONE 或 OpenSSL::SSL::VERIFY_PEER 是可以接受的。

来自https://ruby-doc.org/stdlib-2.7.0/libdoc/net/http/rdoc/Net/HTTP.html

我试图在本地复制它,它与这个修复程序一起工作。

应该是vpn证书是自签名的,需要指定自己的cacert,所以指定cacert文件为上面curl使用的文件,而不是系统自带的cacert文件

添加这一行:

http.ca_file = "cacert filename" 

像这样:

require 'net/http'
require 'json'
require 'uri'

full_url = "https://localhost/test.html"
uri = URI.parse(full_url)

data = { "acb": 123 }
headers = { 'Content-Type' => "application/json" }

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

# You need to specify the cacert file used for curl above (filename: cert.cer)
http.ca_file = "/root/myca/cacert.crt"

request = Net::HTTP::Post.new(uri.request_uri, headers)
request.body = data.to_json

response = http.request(request)

puts response.code
puts response.body

您应该将 .pem 格式的证书添加到(取决于版本):

C:\Ruby{版本号}{-x64 - 如果是 64 位操作系统}\ssl

例如 C:\Ruby25-x64\ssl

或者

C:\Ruby{版本号}{-x64 - 如果是64位操作系统}\lib\ruby{版本号}\rubygems\ssl_certs{你的cn}

例如 C:\Ruby25-x64\lib\ruby\2.5.0\rubygems\ssl_certs\client.cn

然后在 C:\Ruby{版本号}{-x64 - 如果是 64 位操作系统}\ssl\certs 中运行 c_rehash.r 脚本

对于使用 PayPal::SDK.configure(...) 的应用程序

PayPal::SDK.configure(
  mode: ...,
  client_id: ...,
  client_secret: ...,

  # Deliberately set ca_file to nil so the system's Cert Authority is used,
  # instead of the bundled paypal.crt file which is out-of-date due to:
  # https://www.paypal.com/va/smarthelp/article/discontinue-use-of-verisign-g5-root-certificates-ts2240
  ssl_options: { ca_file: nil }
)

对于使用 YAML 配置文件的应用

ssl_options:
  ca_file: null

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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