可能是 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