SSL_connect 返回=1 errno=0 state=SSLv3 读取服务器证书B:证书验证失败

Posted

技术标签:

【中文标题】SSL_connect 返回=1 errno=0 state=SSLv3 读取服务器证书B:证书验证失败【英文标题】:SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed 【发布时间】:2011-05-30 12:15:23 【问题描述】:

我使用Authlogic-Connect 进行第三方登录。运行适当的迁移后,Twitter/Google/yahoo 登录似乎工作正常,但 facebook 登录抛出异常:

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

开发日志显示

OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed):
  app/controllers/users_controller.rb:37:in `update'

请建议..

【问题讨论】:

这有帮助吗:***.com/q/3977303/382818 这是迄今为止我能找到的最佳解决方案***.com/a/16983443/11792 【参考方案1】:

我在尝试使用 Rails 3 的 JQuery 生成器时遇到了类似的问题

我是这样解决的:

    获取 CURL 证书颁发机构 (CA) 包。您可以这样做:

    sudo port install curl-ca-bundle [如果您使用的是 MacPorts] 或者直接拉下来wget http://curl.haxx.se/ca/cacert.pem

    执行尝试验证 SSL 认证的 ruby​​ 代码:SSL_CERT_FILE=/opt/local/etc/certs/cacert.pem rails generate jquery:install。在您的情况下,您希望将其设置为服务器获取它的某个环境变量,或者在您的 environment.rb 文件中添加类似 ENV['SSL_CERT_FILE'] = /path/to/your/new/cacert.pem 的内容。

您也可以只将 CA 文件(我没有尝试过)安装到操作系统 - 有很长的说明 here - 这应该以类似的方式工作,但我没有亲自尝试过。

基本上,您遇到的问题是某些 Web 服务正在使用针对 OpenSSL 无法验证的 CA 签名的证书进行响应。

【讨论】:

这对我也有用,同时尝试使用 Ruby Net::IMAP 从 ruby​​ 脚本连接到我的 gmail 帐户。谢谢。 是的,这在 ruby​​-1.9.3 上运行良好。我将它添加到我的 bash 配置中。 export SSL_CERT_FILE=/usr/local/etc/openssl/certs/cert.pem 我没有/usr/local/etc/openssl,所以我跑了sudo curl http://curl.haxx.se/ca/cacert.pem >> /usr/local/etc/cacert.pem,然后是export SSL_CERT_FILE=/usr/local/etc/cacert.pem 在我的 Mac 上开发时,我刚刚将 SSL_CERT_FILE=/usr/local/etc/openssl/cert.pem 添加到我的应用程序的 .env 文件中,瞧 - 一切都很开心。 我很欣赏使用 wget 下载 curl 证书的讽刺。【参考方案2】:

如果你在 OS X 上使用 RVM,你可能需要运行这个:

rvm osx-ssl-certs update all

更多信息在这里:http://rvm.io/support/fixing-broken-ssl-certificates

这里是完整的解释:https://github.com/wayneeseguin/rvm/blob/master/help/osx-ssl-certs.md


更新

在 Ruby 2.2 上,您可能必须从源代码重新安装 Ruby 才能解决此问题。方法如下(将 2.2.3 替换为您的 Ruby 版本):

rvm reinstall 2.2.3 --disable-binary

归功于https://***.com/a/32363597/4353 和Ian Connor。

【讨论】:

这里有一个更全面的替代方案:railsapps.github.io/openssl-certificate-verify-failed.html 错误:rvm 更新已被删除。请参阅 'rvm get' 和 rvm 'rubygems' CLI API @user432506 你是怎么得到这个错误的?我正在使用最新的稳定 RVM,它仍然有效。 这会工作一段时间,然后对我来说失败了。对我有用的是运行rvm reinstall 2.2.0 --disable-binary,但是你必须捆绑安装并重新开始。 这是一个巨大的救命稻草,应该是公认的答案。【参考方案3】:

在 Windows 上修复它的方法如下:https://gist.github.com/867550(由 Fletcher Nichol 创建)

摘录:

手动方式(无聊)

从http://curl.haxx.se/ca/cacert.pem 下载cacert.pem 文件。将此文件保存到C:\RailsInstaller\cacert.pem

现在通过设置 SSL_CERT_FILE 让 ruby​​ 了解您的证书颁发机构捆绑包。要在当前的命令提示符会话中进行设置,请键入:

set SSL_CERT_FILE=C:\RailsInstaller\cacert.pem

要使其成为永久设置,请将其添加到您的 control panel。

【讨论】:

谢谢。这非常有用,也非常简单。 上述解决方案对我没有帮助。这是一个更好的 Windows 指南:***.com/questions/5720484/… @Sprachprofi 您链接到的解决方案一次仅适用于 1 个 rails 项目(因为您直接指向该证书)。我链接到的要点(由 Fletcher Nichol 创建)将允许它涵盖所有正在寻找证书的项目/宝石。【参考方案4】:

Ruby 找不到任何可信任的根证书。

查看此博客文章以获取解决方案:“Ruby 1.9 and the SSL error”。

解决方案是安装curl-ca-bundle 端口,该端口包含与 Firefox 相同的根证书:

sudo port install curl-ca-bundle

并告诉您的 https 对象使用它:

https.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt'

请注意,如果您希望代码在 Ubuntu 上运行,则需要设置 ca_path 属性,默认证书位置为 /etc/ssl/certs

【讨论】:

这似乎也发生在 Windows 上,在这种情况下,那里推荐的解决方案将不起作用。【参考方案5】:

您在 OSX 上收到此错误的原因是 rvm 安装的 ruby​​。

如果您在 OSX 上遇到这个问题,您可以在这篇博文中找到一个非常广泛的解释:

http://toadle.me/2015/04/16/fixing-failing-ssl-verification-with-rvm.html

简而言之,对于某些版本的 Ruby,RVM 会下载预编译的二进制文件,这些文件会在错误的位置查找证书。通过强制 RVM 下载源代码并在您自己的机器上编译,您可以确保证书位置的配置正确。

执行此操作的命令是:

rvm install 2.2.0 --disable-binary

如果您已经有相关版本,您可以重新安装它:

rvm reinstall 2.2.0 --disable-binary

(显然,根据需要替换您的 ruby​​ 版本)。

【讨论】:

这对我有用。您指向的博文也很有用,谢谢! 这在 El Capitan 上对我有用。我内爆了 rvm(rvm 内爆)。再次使用\curl -sSL https://get.rvm.io | bash -s stable --autolibs=homebrew 安装,然后rvm install <ruby-version> --disable-binary 有一次我也安装了rvm get head,因为这些都是一些前沿问题。 只有这个解决方案对我有用,因为最初我在 El Capitan 上安装了 Ruby 2.0.0,并且由于某种原因,即使使用正确的 SSL_CERT_FILE,旧版本也无法正常工作。在rvm install 2.2.0 --disable-binary之后,问题排序。【参考方案6】:

问题是 ruby​​ 找不到要信任的根证书。从 1.9 开始,ruby 会检查这一点。您需要确保您的系统上具有 pem 文件形式的 curl 证书。您还需要确保证书位于 ruby​​ 期望的位置。您可以在...获得此证书。

http://curl.haxx.se/ca/cacert.pem

如果您是 RVM 和 OSX 用户,那么您的证书文件位置将根据您使用的 ruby​​ 版本而有所不同。使用 :ca_path 显式设置路径是一个坏主意,因为您的代码在投入生产时将不可移植。在那里,您想在默认位置为 ruby​​ 提供证书(并假设您的开发人员知道他们在做什么)。您可以使用 dtruss 确定系统在哪里寻找证书文件。

在我的情况下,系统正在寻找证书文件

/Users/stewart.matheson/.rvm/usr/ssl/cert.pem

但是 MACOSX 系统需要证书

/System/Library/OpenSSL/cert.pem

我将下载的证书复制到此路径并且它有效。高温

【讨论】:

对于 Ubuntu 12.04 上的我来说,有效的证书路径是 ~/.rvm/usr/ssl/cert.pem 如何使用 dtruss 确定系统在哪里寻找证书? @pingu 基本上不记得你运行 druss 的确切命令,然后你告诉它运行你希望它“检查”的任何 ruby​​ 进程。它的输出非常冗长,但基本上你将能够看到 ruby​​ 正在进行的每个系统调用。其中一个调用是读取文件调用,它将指向一个不存在的文件。将证书移至此处或创建链接,您应该一切顺利。 Ruby 不应该在 OS X 上寻找cacert.pem。OS X 不使用cacert.pem。系统和用户证书存储在 KeyChain 中。 Ruby 应该与 OS X 上的 KeyChain 集成。 最好的方法是什么?可以举个例子吗?【参考方案7】:

新的认证 gem 旨在解决这个问题:

https://github.com/stevegraham/certified

【讨论】:

适用于 ruby​​ 2.0.0p481 (2014-05-08) [i386-mingw32] 不适用于 Rails 4.1.9、ruby-2.1.5。我将它添加到 Gemfile,bundle,明确添加了require "certified",只是为了确定,没有任何变化。我错过了什么? Ruby 不应该在 OS X 上寻找cacert.pem。OS X 不使用cacert.pem。系统和用户证书存储在 KeyChain 中。 Ruby 应该与 OS X 上的 KeyChain 集成。OpenSSL从未分发过cacert.pem。我不清楚为什么任何软件都会为它遵循 OpenSSL。【参考方案8】:

只需在您的 gemfile 中添加 gem 'certified' 并运行 bundle install。

    gem '认证' 捆绑安装

【讨论】:

确认这有助于 El Capitan。谢谢! 它与 Rails 和 Debian 完美配合 :) 非常感谢!【参考方案9】:

在带有最新 macport 的 Mac OS X Lion 上:

sudo port install curl-ca-bundle  
export SSL_CERT_FILE=/opt/local/share/curl/curl-ca-bundle.crt  

然后,重新运行失败的作业。

请注意,自 Eric G 于 5 月 12 日回答以来,证书文件位置似乎已更改。

【讨论】:

经过所有的搜索和多次尝试,这是唯一解决问题的方法。谢谢! 酷,解决了它。但是只要用 homebrew 安装了 openssl,你就必须在你的 .profile 或 .bashrc 文件中添加一个export SSL_CERT_FILE=/usr/local/etc/openssl/cacert.pem【参考方案10】:

一个内衬在管理员提示符下为 Windows 修复它

choco install wget(先见chocolatey.org)

wget http://curl.haxx.se/ca/cacert.pem -O C:\cacert.pem && setx /M SSL_CERT_FILE "C:\cacert.pem"

或者只是这样做:

gem sources -r https://rubygems.org/
gem sources -a http://rubygems.org/

米兰尼奥的方法:

gem sources -r https://rubygems.org
gem sources -a http://rubygems.org 
gem update --system
gem sources -r http://rubygems.org
gem sources -a https://rubygems.org

gem install [NAME_OF_GEM]

【讨论】:

小改进 - 你只需要更新 ruby​​,然后你可以添加 https 源 - 这对我来说就像一个魅力:gem sources -r rubygems.org => gem sources -a @987654323 @ => gem update --system => gem sources -r rubygems.org => gem sources -a rubygems.org => gem install [NAME_OF_GEM] 获取rubygems.org时出错:SSL_connect 返回=1 errno=0 state=error:证书验证失败(无法获取本地颁发者证书)(api.rubygems.org/specs.4.8.gz)【参考方案11】:

这对我有用

rvm pkg install openssl
rvm reinstall 1.9.2 --with-openssl-dir=$rvm_path/usr

我的 ubuntu 12.04 的 openssl 实现有问题

【讨论】:

这可行,但我必须完成这个:curl -O http://curl.haxx.se/ca/cacert.pemmv cacert.pem cert.pemmv cert.pem $rvm_path/usr/ssl 为我工作,Mac OS X Yosemite。谢谢!【参考方案12】:

这是用于调试目的的另一个选项。

千万不要在任何生产环境中使用它,因为它首先会抵消使用 SSL 的好处。仅在本地开发环境中执行此操作才有效。

require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

【讨论】:

否决:是的,这行得通,但安装有效 CA 包并实际解决问题的障碍是如此之低,以至于像这样的解决方案 - 几乎完全使 SSL 的安全性无效 - 不是除非您处于证书颁发机构完全无法访问的环境中,否则应该实施的解决方案(即使那样,您也应该创建一个可供两个端点访问的本地 CA)。 它并没有完全移除 SSL 保护,而是完全移除了它。永远不要这样做。 调试就足够了 这会在 1.9 中产生警告 这对于在实际 Internet 上的生产工作来说是一个糟糕的解决方案,但“你可能根本不使用 SSL”是不正确的。通过网络加密的流量优于明文流量。是的,您有可能受到中间人攻击,但与简单地窃听经过的明文流量相比,这些攻击至少更难站稳脚跟。【参考方案13】:

虽然知道这是一个相当蹩脚的解决方案,但我仍然分享这个,因为似乎很少有人在这里回答使用 Windows,我认为一些 Windows 用户(包括我在内)会喜欢简单直观的方法。

require 'openssl'
puts OpenSSL::X509::DEFAULT_CERT_FILE

这告诉您 openssl 在哪里寻找证书文件。我的名字不是路易斯,但我的名字是C:/Users/Luis/Code/luislavena/knap-build/var/knapsack/software/x86-windows/openssl/1.0.0l/ssl/cert.pem。路径可能因每个自己的环境而异(例如 openknapsack 而不是 luislavena)。

即使在通过控制台set SSL_CERT_FILE=C:\foo\bar\baz\cert.pem 之后路径也没有改变,所以...我在本地磁盘中创建了目录 C:\Users\Luis\Code\luislavena\knap-build\var\knapsack\software\x86-windows\openssl\1.0.0l\ssl 并将证书文件放入其中。

虽然很蹩脚,这肯定会奏效。

【讨论】:

太棒了。哈基,但这是唯一解决我问题的方法。 调试的好方法......对我来说,用户是“贾斯汀”。谷歌搜索显示这似乎是 RubyInstaller 的一个已知问题。不幸的是,我自己创建该目录(+ pem 文件)并没有为我解决问题【参考方案14】:

我已经尝试安装curl-ca-bundlebrew,但该软件包不再可用:

$ brew install curl-ca-bundle
Error: No available formula for curl-ca-bundle 
Searching formulae...
Searching taps...

在 Mac 上对我有用的解决方案是:

 $ cd /usr/local/etc/openssl/certs/
 $ sudo curl -O http://curl.haxx.se/ca/cacert.pem

将此行添加到您的 ~/.bash_profile(或 ~/.zshrc 用于 zsh)中:

export SSL_CERT_FILE=/usr/local/etc/openssl/certs/cacert.pem

然后更新你的终端:

$ source ~/.bash_profile

【讨论】:

这对我有用 - 但路径错误。应该是:export SSL_CERT_FILE=/usr/local/etc/openssl/certs/cacert.pem 这是一个很好的解决方案,因为它很简单。此外,通过在 ~/.bash_profile 中引用添加的证书,它会在需要进一步更新时提醒您添加了什么(以及关键的位置)。 这对我有用。 @dnlmzw 路径对我来说很好,但这当然取决于您的设置。谢谢! 在尝试将使用自签名证书的私有 gem 服务器 URL 添加到我的 gem 源时对我不起作用。 OSX 10.11.6 + rbenv【参考方案15】:

我在处理 Ruby 项目时遇到了同样的问题。我正在使用 Windows 7 64 位。

我通过以下方式解决了这个问题:

    从http://curl.haxx.se/ca/cacert.pem下载cacert.pem文件。 将该文件保存到 C:/RubyCertificates/cacert.pem 然后将我的环境变量“SSL_CERT_FILE”设置为“C:\RubyCertificates\cacert.pem”

来源:https://gist.github.com/fnichol/867550

【讨论】:

由于是Windows,所以环境变量的值要使用反斜杠。 在修复 ruby​​gems ssl 错误后,这是为我修复“捆绑”的唯一解决方案【参考方案16】:

对我有用的最直接的答案是这个

sudo apt-get install openssl ca-certificates

然后瞧!!!

【讨论】:

希望我能多次投票,因为你为我节省了很多时间! @Stephen - 我希望你也可以:-)。它为我节省了很多时间,所以我想我会把它贴在这里,它也可能对其他人有所帮助。【参考方案17】:

带有 Homebrew 的 OS X 10.8.x:

brew install curl-ca-bundle
brew list curl-ca-bundle
cp /usr/local/Cellar/curl-ca-bundle/1.87/share/ca-bundle.crt /usr/local/etc/openssl/cert.pem

【讨论】:

在 10.9 上也适用于我。 好吧,OS X 10.9.1。太棒了! 当你不得不寻找随机的解决方案来解决这些愚蠢的问题时,有些东西被严重破坏了。所有这些答案都做了一些完全不同的事情,而且它们似乎都在某些时候对人们有所帮助。什么鬼? curl-ca-bundle 已从 brew 中移除【参考方案18】:

然后,正如这篇博文所建议的,

“How to Cure Net::HTTP’s Risky Default HTTPS Behavior”

您可能想要安装always_verify_ssl_certificates gem,它允许您为ca_file 设置默认值。

【讨论】:

【参考方案19】:

这对我有用。如果您使用 rvm 和 brew:

rvm remove 1.9.3
brew install openssl
rvm install 1.9.3 --with-openssl-dir=`brew --prefix openssl`

【讨论】:

【参考方案20】:

我遇到了这个问题,尽管我是 OSX 上的 RVM 用户,但建议的 rvm osx-ssl-certs update all 修复仍然无效。

对我有用的修复是重新安装最新版本的 openssl:

brew update
brew remove openssl
brew install openssl

【讨论】:

【参考方案21】:

我通过在终端中运行它解决了这个问题。完整的文章可通过here 获得

rvm install 2.2.0 --disable-binary

【讨论】:

【参考方案22】:

如果您在本地运行您的 rails 应用程序,那么只需在 application.rb 的底部添加这一行。

OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

在此之后,您可以毫无问题地使用该应用程序。您可以将其称为 hack,但不建议这样做。仅在需要本地运行时使用

【讨论】:

【参考方案23】:

OSX 解决方案:

安装最新的 rvm 稳定版

rvm get stable

使用 rvm 命令自动解析证书

rvm osx-ssl-certs update all

【讨论】:

我试过了,但它对我不起作用。这是我的解决方案:***.com/a/16741712/62 在通过 RVM 安装 Ruby 2.0.0 后为我工作。【参考方案24】:

如果您在 Leopard 上遇到具体问题,这就是我所做的帮助。

我的证书很旧,需要更新。我下载了这个:

http://curl.haxx.se/ca/cacert.pem

然后替换了我在 Leopard 上找到的证书:

/usr/share/curl/curl-ca-bundle.crt

重新加载任何可以访问它的东西,你应该一切顺利!

【讨论】:

【参考方案25】:

仅仅因为对我有用的说明略有不同,我想我加了 2 美分:

我在 OS X Lion 上使用 macports 和 rvm

我安装了 curl-ca-bundle:

sudo port install curl-ca-bundle

然后我将omniauth配置调整为:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, APP_CONFIG['CONSUMER_KEY'], APP_CONFIG['CONSUMER_SECRET'],
           :scope => 'https://www.google.com/m8/feeds https://www.googleapis.com/auth/userinfo.profile',
           :ssl => :ca_path => "/share/curl/curl-ca-bundle.crt"
end

【讨论】:

您可以(并且可能应该)放弃整个 CA Zoo (ca-bundle.crt) 并在:ssl => :ca_path => "/share/curl/curl-ca-bundle.crt" 中使用Google Internet Authority G2。这是唯一需要证明与 Google 的连接。【参考方案26】:

如果 /usr/local/etc/openssl 中有指向 cert.pem 的符号链接,请尝试这样做:

ruby -ropenssl -e "p OpenSSL::X509::DEFAULT_CERT_FILE" (should be /usr/local/etc/openssl)
cd /usr/local/etc/openssl
wget http://curl.haxx.se/ca/cacert.pem
ln -s cacert.pem 77ee3751.0 (77ee3751.0 is my symbolic link, should depend on the openssl version)

【讨论】:

【参考方案27】:

对我有用的是答案的组合,即:

# Reinstall OpenSSL
brew update
brew remove openssl
brew install openssl
# Download CURL CA bundle
cd /usr/local/etc/openssl/certs
wget http://curl.haxx.se/ca/cacert.pem
/usr/local/opt/openssl/bin/c_rehash
# Reinstall Ruby from source
rvm reinstall 2.2.3 --disable-binary

【讨论】:

【参考方案28】:

我有好几天都遇到了麻烦,而且一直在乱搞。 This link 被证明对我非常有帮助。它帮助我在 MAC OS X 9 上成功升级了 SSL。

【讨论】:

【参考方案29】:

有时并不总是 rvm 的问题 在 MAC OSX 中,如果你删除 .rvm,问题仍然存在(尤其是当你从 timemachine 备份数据时),你可以试试这个方法。

1.brew update
2.brew install openssl

【讨论】:

【参考方案30】:

gem 'certified', '~> 1.0' 添加到我的Gemfile 并运行bundle 为我解决了这个问题。

【讨论】:

以上是关于SSL_connect 返回=1 errno=0 state=SSLv3 读取服务器证书B:证书验证失败的主要内容,如果未能解决你的问题,请参考以下文章

SSL_connect (Errno::ECONNRESET)

Ruby SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B:

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

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

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

OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv3/TLS write client hello