Ruby SSL error - sslv3 alert unexpected message

前端 未结 5 2105
青春惊慌失措
青春惊慌失措 2020-12-10 18:05

I\'m trying to connect to the server https://www.xpiron.com/schedule in a ruby script. However, when I try connecting:

require \'open-uri\'
doc          


        
相关标签:
5条回答
  • 2020-12-10 18:32

    I think it's because of the https URL. There's a mean, completely insecure hack for bypassing this, but please google for it at your own risk. I will rather show you the secure way of doing it, using Net::HTTP:

    require 'net/http'
    
    url = URI.parse('https://www.xpiron.com/schedule')
    req = Net::HTTP::Get.new(url.path)
    sock = Net::HTTP.new(url.host, 443)
    sock.use_ssl = true
    store = OpenSSL::X509::Store.new
    store.add_cert OpenSSL::X509::Certificate.new(File.new('addtrust_ca.pem'))
    store.add_cert OpenSSL::X509::Certificate.new(File.new('utn.pem'))
    store.add_cert OpenSSL::X509::Certificate.new(File.new('user_first_ca.pem'))
    store.add_cert OpenSSL::X509::Certificate.new(File.new('xpiron.pem'))
    sock.cert_store = store
    sock.start do |http|
      response = http.request(req)
    end
    

    You may obtain the certificate files by entering your URL in the browser (e.g. Firefox), and then clicking on the icon left of the URL/More Information/View Certificate/Details -> there click on each certificate in the chain and export it as a PEM file under the names I used above. Put these files in the same directory as the script referencing them. That should do the magic. But I noticed that a cookie is required to login to that page, so it might require a bit more effort of modifying your request appropriately.

    0 讨论(0)
  • 2020-12-10 18:41

    After a full day of hacking, this one finally worked for me:

    url = URI.parse("https://full-url?test=1&foo=bar")
    response = Net::HTTP.start(url.host, use_ssl: true, ssl_version: 'SSLv3', verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
      http.get url.request_uri
    end
    
    0 讨论(0)
  • 2020-12-10 18:47

    Note that rest-client gem does not have a means to set this as of this writing. There is an outstanding pull request but the gem does not appear to be maintained, unfortunately.

    0 讨论(0)
  • 2020-12-10 18:50

    It can be

    require 'openssl'
    OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
    
    0 讨论(0)
  • 2020-12-10 18:51

    Just to answer my own question.

    The problem seems to be with how Ruby negotiates SSL connections. There's an error in Xpiron's TLS mechanism, and it throws an error instead of retrying to other SSL versions.

    If you force the SSL version to 3.0, it works:

    require 'net/http'
    url = URI.parse('https://www.xpiron.com/schedule')
    req = Net::HTTP::Get.new(url.path)
    sock = Net::HTTP.new(url.host, 443)
    sock.use_ssl = true
    sock.ssl_version="SSLv3"
    sock.start do |http|
        response = http.request(req)
    end
    

    I also created an issue on Ruby's bug tracker.

    0 讨论(0)
提交回复
热议问题