为什么红宝石无法验证​​SSL证书? [英] Why is Ruby unable to verify an SSL certificate?

查看:226
本文介绍了为什么红宝石无法验证​​SSL证书?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次尝试使用XMLRPC :: Client库与远程API交互,我不断收到此错误:

This is my first time trying to use the XMLRPC::Client library to interact with a remote API and I keep receiving this error:

warning: peer certificate won't be verified in this SSL session

搜索中已经得到了错误的人身边,我发现负载。通常它的使用自签名的证书,他们只是希望它去了,所以他们不喜欢猴子脏东西打补丁的方式XMLRPC ::客户端打开它的HTTP会话。

Searching around I've found loads of people that have gotten that error. Usually it's with self-signed certificates and they just want it to go away, so they do something dirty like monkey patch the way XMLRPC::Client is opening it's http session.

我首先假定这只是客户不关心该证书是否有效与否,所以我继续我的搜索和整个这种宝石<来了/ A>。它简单地让所有的SSL证书验证,并引发一个严重的错误,如果它不能太大。而这,正是我想要的。我把它,再次运行code现在我得到这样的:

I first assumed this was simply the client not caring whether the certificate was valid or not, so I continued my search and came across this gem. It simply forces verification of all SSL certificates and throws a hard error if it's not able too. This was exactly what I wanted. I included it, ran the code again and now I'm getting this:

OpenSSL:SSL::SSLError:
  SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B:
  certificate verify failed

当然!该证书是坏的!但我仔细检查,以确保公正与OpenSSL的,像这样内建的s_client.First:

Of course! The certificate is bad! But I double check just to make sure with openssl's builtin s_client like so:

openssl s_client -connect sub.example.com:443

和我能得到什么:

CONNECTED(00000003)
---
Certificate chain
<snip>
Verify return code: 0 (ok)

所以,现在我们得到了我的问题。 OpenSSL的(命令行版本)说,证书是不错的。 OpenSSL的(Ruby的库)不同意。我所有的网页浏览器说,证书是不错的。

So now we get to my question. OpenSSL (the command line version) says the certificate is good. OpenSSL (the Ruby library) disagrees. All of my web browsers say the certificate is good.

一些其他细节,可能会使用。该证书是一个通配符,但有效域。在OpenSSL的s_client.First是在同一台机器秒除了红宝石code运行。这是红宝石是安装RVM。1.8.7 P357

A few additional details that might be of use. The certificate is a wildcard but is valid for the domain. The openssl s_client was run on the same machine seconds apart from the Ruby code. This is Ruby 1.8.7 p357 which is installed with RVM.

红宝石是否使用不是由主机操作系统提供的CA捆绑其他​​的东西吗?有没有一种方法来告诉Ruby来使用特定的CA软件包或系统中的一个?

Does Ruby use something other than the CA bundle provided by the host OS? Is there a way to tell Ruby to use a specific CA bundle or the system one?

推荐答案

如果你只关心如何让Ruby的行为方式与OpenSSL的相同的s_client.First 或浏览器确实,你可以跳到了最后一节,我会在什么下面小字。

If you are only interested in how to make Ruby behave the same way as OpenSSL s_client or your browser does, you may skip to the very last section, I'll cover the fine print in what is following.

默认情况下,使用了的OpenSSL :: X509 ::商店制作的连接不使用任何受信任的证书都没有。根据您的应用领域的知识,你通常会处理有关您的应用程序中的可信证书(S)饲料 X509的实例::商店。有几个选项是:

By default, the OpenSSL::X509::Store used for making the connection doesn't use any trusted certificates at all. Based on your knowledge of the application domain, you would typically feed an instance of X509::Store with the trusted certificate(s) that are relevant for your application. There are several options for this:


  • 商店#add_file需要一个路径到PEM / DER-EN codeD证书

  • 商店#add_cert采用X509 ::证书
  • 的实例
  • 商店#add_path花费目录的路径,其中受信任的证书,可以发现

这是对比的方式浏览器,Java的储存区(cacerts),或Windows受信任的证书的自身的内部存储,取。目前该软件是pre配备了一组被认为是好的软件供应商的意见受信任的证书。一般来说,这不是一个坏主意,但如果你真的考虑这些集,那么你很快就会发现,有太多的证书。一个人真的不能告诉是否的所有的这些证书应该盲目或者不被信任。

This is in contrast to the approach browsers, Java (cacerts), or Windows with its own internal store of trusted certificates, take. There the software is pre-equipped with a set of trusted certificates that is considered to be "good" in the opinion of the software vendor. Generally this is not a bad idea, but if you actually look into these sets, then you will soon notice that there are just too many certificates. An individual can't really tell whether all of these certificates should be trusted blindly or not.

在另一方面典型的Ruby应用程序的要求比浏览器的一个很大的不同。浏览器必须能够让你导航到配有TLS证书,并通过https提供任何合法的网站。但是,在一个典型的Ruby应用程序,您将只需要处理与使用TLS或否则需要证书验证服务而已。

The requirements of your typical Ruby application on the other hand are a lot different than that of a browser. A browser must be be able to let you navigate to any "legitimate" web site that comes with a TLS certificate and is served over https. But in a typical Ruby application you will only have to deal with a few services that use TLS or would otherwise require certificate validation.

还有就是Ruby的方式的好处 - 尽管它需要更多的手动工作,你最终会与准确信任它应该在给定的应用程序上下文信任证书的手工定制的解决方案。这是乏味的,但安全性更高的这种方式,因为你暴露少了很多攻击面。就拿最近发生的事件:如果你从未有过的包括DigiNotar或您的信任设置任何其他损害的根,那么有没有办法这种违法行为会影响您

And there is the benefit of the Ruby approach - although it requires more manual work, you will end up with a hand-tailored solution that exactly trusts the certificates it should trust in your given application context. This is tedious, but security is much higher this way because you expose a lot less attack surface. Take recent events: if you never had to include DigiNotar or any other compromised root in your trust set, then there's no way such breaches can affect you.

这种方法的缺点,但是,因为你已经注意到了,就是在默认情况下,如果你不主动添加受信任的证书,OpenSSL的扩展将无法验证的任何的同行证书在所有。为了使事情的工作,你必须手动设置配置。

The downside of this, however, as you have already noticed, is that by default, if you don't actively add trusted certificates, the OpenSSL extension will not be able to validate any peer certificate at all. In order to make things work, you have to set up the configuration manually.

此不便导致了很多可疑的措施来规避它,最糟糕的是在全球范围内设置的 OpenSSL的SSL :: :: VERIFY_PEER = OpenSSL的SSL :: :: VERIFY_NONE 。请不要这样做。我们甚至开玩笑约增加code,可以让你的应用程序崩溃随机,如果我们遇到黑客:)

This inconvenience has led to a lot of dubious measures to circumvent it, the worst of all being to globally set OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE. Please don't do this. We have even made jokes about adding code that lets your application crash randomly if we encounter that hack :)

如果手动信任设置似乎太复杂了,我现在就提供了一个很不错的选择,使OpenSSL的扩展行为完全一样OpenSSL的CLI命令,如的s_client.First

If manual trust setup seems too complicated, I'll offer an easy alternative now that makes the OpenSSL extension behave exactly the same as OpenSSL CLI commands like s_client.

OpenSSL的使用类似的方法来浏览器和Windows。典型安装将放在可信证书的某处捆绑您的硬盘上(类似 /etc/ssl/certs/ca-bundle.crt ),这将作为缺省设置可信证书。这就是的s_client.First 看起来,当它需要验证对等证书,这就是为什么你的实验成功了。

OpenSSL uses a similar approach to browsers and Windows. A typical installation will put a bundle of trusted certificates somewhere on your hard disk (something like /etc/ssl/certs/ca-bundle.crt) and this will serve as the default set of trusted certificates. That's where s_client looks when it needs to verify peer certificates and that's why your experiment succeeded.

如果您仍然想使用Ruby验证证书时有相同的舒适性,你可以告诉它通过调用使用,如果你的系统上的受信任的证书OpenSSL的束 OpenSSL的:: X509: :存储#set_default_paths 。更多信息可以在这里找到 。与 XMLRPC使用该客户端:: ,只需确保 set_default_paths 被调用的 X509 ::商店它使用了。

If you'd still like to have the same comfort when validating certificates with Ruby, you can tell it to use the OpenSSL bundle of trusted certificates if available on your system by calling OpenSSL::X509::Store#set_default_paths. Additional information can be found here. To use this with XMLRPC::Client, simply ensure that set_default_paths gets called on the X509::Store it uses.

这篇关于为什么红宝石无法验证​​SSL证书?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆