2

我已经尝试了一切来解决这个问题,但没有任何工作。我已经卸载了所有东西并重新安装了。还是没有爱。这是我尝试连接到 Evernote API 时遇到的错误。

OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A

我正在运行:RVM 1.15.9
Ruby 1.9.3-p194
OpenSSL 1.0.1c
Rails 3.2.8
Homebrew 0.9.3

我已经尝试了一切。遵循本指南http://railsapps.github.com/openssl-certificate-verify-failed.html

尝试使用 Evernote API,这就是这一切的开始。cURL 可以很好地 ping HTTPS 地址。干杯。

4

1 回答 1

3

可能是 SSL v2 和 v3 之间的问题。

命令行诊断:

要诊断此问题,请在命令行上尝试:

$ openssl s_client -connect sandbox.evernote.com:443

该命令可能会像这样失败:

CONNECTED(00000003)
140386475906720:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure
...

现在只用 SSL3 试试:

openssl s_client -no_tls1 -no_ssl2 -ssl3 -connect  sandbox.evernote.com:443

你想得到这样的结果:

CONNECTED(00000003)
depth=2 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network
...

如果第一个命令失败,而第二个命令成功,那么问题很可能是 SSL2 与 SSL3。

红宝石诊断:

#!/usr/bin/env ruby                                                                                                                                                                                                                                                              
require 'net/http'
uri = URI.parse('https://sandbox.evernote.com/')
req = Net::HTTP::Get.new(uri.path)
sock = Net::HTTP.new(uri.host, 443)
sock.use_ssl = true

# Try with default SSL                                                                                                                                                                                                                                                           
begin
  sock.start do |http|
    response = http.request(req)
  end
  puts "success with SSL default"
rescue
  puts "failure with SSL default"
end

# Try with just SSL3                                                                                                                                                                                                                                                             
sock.ssl_version="SSLv3"
begin
  sock.start do |http|
    response = http.request(req)
  end
  puts "success with SSLv3"
rescue
  puts "failure with SSLv3"
end

如何修复它:

警告:这是一个黑客。使用风险自负。如果有人找到更好的方法来做到这一点,请在此处发表评论。

修补 HTTP.new 以强制它始终使用 SSLv3

require 'net/http'
module Net
  class HTTP < Protocol
    def HTTP.new(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil)
      socket = Proxy(p_addr, p_port, p_user, p_pass).newobj(address, port)
      socket.ssl_version = "SSLv3"
      socket
    end
  end
end

uri = URI.parse('https://sandbox.evernote.com/')
req = Net::HTTP::Get.new(uri.path)
sock = Net::HTTP.new(uri.host, 443)
sock.use_ssl = true

# Try with default SSL                                                                                                                                                                                                                                                           
begin
  sock.start do |http|
    response = http.request(req)
  end
  puts "success with SSL default"
rescue
  puts "failure with SSL default"
end
于 2012-09-20T15:19:35.070 回答