Ruby 使用https连接到具有由我创建的CA签名的证书的服务器

Ruby 使用https连接到具有由我创建的CA签名的证书的服务器,ruby,ssl,https,ssl-certificate,Ruby,Ssl,Https,Ssl Certificate,我有一个测试环境,它使用Ruby通过https连接驱动服务器。由于最新版本的Ruby拒绝使用无效证书连接到https服务器(请参阅),并且我想开始使用更新版本的Ruby,因此我正在尝试设置有效的证书 我已经创建了一个要使用的CA证书(有多个服务器正在测试,因此这似乎是更简单的方法),并成功地使用它来签署一个已安装在服务器上并正在使用的新证书。我已将CA证书添加到浏览器存储中,它(浏览器)现在将毫无怨言地连接到服务器。因此,我相信我的证书是有效的,并且设置正确 我知道Ruby不使用与浏览器相同的存

我有一个测试环境,它使用Ruby通过https连接驱动服务器。由于最新版本的Ruby拒绝使用无效证书连接到https服务器(请参阅),并且我想开始使用更新版本的Ruby,因此我正在尝试设置有效的证书

我已经创建了一个要使用的CA证书(有多个服务器正在测试,因此这似乎是更简单的方法),并成功地使用它来签署一个已安装在服务器上并正在使用的新证书。我已将CA证书添加到浏览器存储中,它(浏览器)现在将毫无怨言地连接到服务器。因此,我相信我的证书是有效的,并且设置正确

我知道Ruby不使用与浏览器相同的存储。我已经使用了CA文件来测试与其他(公共)服务器的连接(使用
Net::HTTP#CA#u file=
方法设置),这也可以工作

我无法工作的是Ruby使用我的证书连接到我的服务器。我尝试了各种方法将其指向我的证书(包括将我的证书添加到上面链接的文件),但它总是会出现相同的错误:

SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A (OpenSSL::SSL::SSLError)
我必须做什么才能说服Ruby接受我的证书并连接到我的服务器

我使用的代码是:

require 'net/https'

uri = URI.parse("https://hostname/index.html")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.ca_file = "My CA cert file"
request = Net::HTTP::Get.new(uri.path)
response = http.request(request)

我想这是错的。我想知道的是,我应该如何使用我的CA证书?

确保您的证书文件是PEM格式的,而不是CRT格式的(如用户所说)


更新看起来文档不是最新的,Ruby 1.9.3将接受任何类型的证书。

我假设您的Tomcat不喜欢Ruby尝试协商的协议版本。Ruby在默认情况下使用,但我也听说过其他情况,这是基于Java的web服务器的一个问题。您收到的错误消息表明,在建立连接并尝试读取服务器响应时,握手失败。尝试添加其中一个

http.ssl_version = :TLSv1

看看这是否有帮助


如果这还不能解决问题,那么了解服务器拒绝连接尝试的原因将非常有趣。尝试使用
-Djavax.net.debug=ssl运行Tomcat,并请发布相关部分(连接信息、异常堆栈跟踪),说明尝试失败的原因。

我使用ruby 1.9.3,在使用nokogiri解析一些安全URL时遇到了相同的错误

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: (null)
浮雕提供的上述答案是正确的,但请确保生成的ssl错误就是上述错误。我遵循同样的方法,找到了下面提到的解决方案

uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.ssl_version = :SSLv3
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
response = http.get(url)

现在,响应正在为传递给url中的代码的安全url解析正确的html

你说你也用Ruby运行你的服务器?你能为客户端和服务器发布相关的代码片段吗?@emboss服务器不是Ruby(它实际上是tomcat,尽管我认为这不重要)。我不确定你想看什么代码。我只是在使用标准的Ruby https库。@Jonathan,粘贴用于连接到服务器的客户端代码将是一个起点。这无关紧要。Ruby可以处理(捆绑的)PEM证书文件以及DER编码的证书。这是它的一个方便的功能实际上,你不需要关心你的证书的格式。文档上说不是这样,但我相信你,我从未尝试过使用非PEM证书。哦,对不起,那么我需要更新文档:)我的错,你能做一个微编辑吗,这样我就可以取消否决票了?我添加了一个到文档的链接(我应该从一开始就添加它)。这很有效!非常感谢你。我知道这一定是我错过的简单的东西!不客气!事实上,你也可以帮我。我需要弄清楚这是否是Java方面的真正错误。在客户端使用SSLv23就像告诉服务器“我可以做任何你想要我做的协议,只要说出它的名字就行了”,所以Tomcat一开始就不应该拒绝。您使用的是哪个Tomcat版本,哪个JDK?出于兴趣,如果您碰巧知道的话,最近是否更改了此默认值?此问题仅在最新版本(1.8.7-p352和1.9.2p290)中出现。早期版本可以,Java版本是1.6.0_05-b13。Tomcat版本是6.0.35。@Jonathan嗯,我不知道。Git说我们从2003年开始使用SSLv23:L149。您是否同时更改了OpenSSL本身?
uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.ssl_version = :SSLv3
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
response = http.get(url)