SSLError:主机名“WXYZ”与服务器证书不匹配

我刚开始学习Ruby,经过一些基本的事情,我试图理解在ruby中对REST服务进行REST调用。 我可以毫不费力地向foursquare API提出请求。 另一方面,对Cisco CMX API的调用会出错。 我的ruby版本是2.1.2。 我在网上搜索了很多解决方案,但仍然遇到问题。 这是我运行的shell命令。

工作一

$resclient >> RestClient.get 'https://api.foursquare.com/v2/venues/search?ll=40.7,-74&oauth_token=0ZDO1JMJ0PW2QTCDK50OGZ21UENHZ0Y3KIDQZJLLURTQNRQ2&v=20150106' 

这给出了错误

 $restclient >> RestClient.get 'https://learning:learning@64.103.26.61/api/contextaware/v1/maps/.json' 

我的错误日志:

 OpenSSL::SSL::SSLError: hostname "64.103.26.61" does not match the server certificate from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/openssl/ssl.rb:139:in `post_connection_check' from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:922:in `connect' from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:863:in `do_start' from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:852:in `start' from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient/request.rb:413:in `transmit' from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient/request.rb:176:in `execute' from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient/request.rb:41:in `execute' from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient.rb:65:in `get' from (irb):3 from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/bin/restclient:93:in `' from /Users/apple/.rbenv/versions/2.1.2/bin/restclient:23:in `load' from /Users/apple/.rbenv/versions/2.1.2/bin/restclient:23:in `' 

你能给点建议吗? 谢谢

你能给点建议吗?

这是一个更详细的答案,以及如何使用可怜的OpenSSL::SSL::VERIFY_NONE之外的其他东西解决Ruby中的问题。

 $ openssl s_client -connect 64.103.26.61:443 | openssl x509 -text -noout depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2 ... Subject: C=US, ST=CA, L=San Jose, O=Cisco Systems, Inc., CN=msesandbox.cisco.com ... X509v3 Subject Alternative Name: DNS:msesandbox.cisco.com 

因此,设备的DNS名称为msesandbox.cisco.com。 nslookup告诉你它一个好的主机名:

 $ nslookup msesandbox.cisco.com Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: Name: msesandbox.cisco.com Address: 64.103.26.61 

因此,您要做的第一件事是通过DNS名称连接到它,而不是IP地址。

如果您为cisco.com域颁发证书(或可以发出请求),则可以要求将IP地址64.103.26.61添加为主题备用名称(SAN) 。 因此证书中将有两个SAN。


现在,如果你回到openssl命令:

 $ openssl s_client -connect 64.103.26.61:443 | openssl x509 -text -noout depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2 verify error:num=19:self signed certificate in certificate chain ... Issuer: C=US, O=HydrantID (Avalanche Cloud Corporation), CN=HydrantID SSL ICA G2 ... Subject: C=US, ST=CA, L=San Jose, O=Cisco Systems, Inc., CN=msesandbox.cisco.com 

您将看到发行人和主题不同。 这意味着这不是自签名证书。 该证书由HydrantID(Avalanche Cloud Corporation)颁发。

如果再往前看,您会看到Issuer的公钥(Authority Key Identifier)与Subject的公钥(Subject Key Identifier)不同:

 X509v3 Authority Key Identifier: keyid:98:6A:B6:2D:2E:BF:A7:AA:9F:F6:F7:D6:09:AF:D5:8B:57:F9:8A:B7 ... X509v3 Subject Key Identifier: B5:3D:50:53:0A:A2:06:9E:9A:29:89:7A:AB:96:90:FE:9D:6B:57:A0 

再次,它不是自签名的。


如果再次返回OpenSSL命令,您将看到发行者是HydrantID SSL ICA G2 ,其发行者是QuoVadis Root CA2 G3

 depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2 verify return:1 depth=1 C = US, O = HydrantID (Avalanche Cloud Corporation), CN = HydrantID SSL ICA G2 verify return:1 depth=0 C = US, ST = CA, L = San Jose, O = "Cisco Systems, Inc.", CN = msesandbox.cisco.com verify return:1 

这意味着QuoVadis Root CA2 G3发布了HydrantID SSL ICA G2 ; 和HydrantID SSL ICA G2发布了msesandbox.cisco.comQuoVadis Root CA2 G3是食物链中的佼佼者。

您可以从QuoVadis CA证书下载中获取QuoVadis Root CA2 G3

 $ curl -O -J -L https://www.quovadisglobal.bm/Repository/~/media/Files/Roots/quovadis_rca2g3_der.ashx % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1380 100 1380 0 0 1808 0 --:--:-- --:--:-- --:--:-- 5726 curl: Saved to filename 'quovadis_rca2g3_der.cer' $ openssl x509 -in quovadis_rca2g3_der.cer -inform DER -out quovadis-ca.pem -outform PEM $ cat quovadis-ca.pem -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 ... -----END CERTIFICATE----- 

如果您信任QuoVadis认证设备,则:

 $ openssl s_client -connect msesandbox.cisco.com:443 -CAfile quovadis-ca.pem CONNECTED(00000003) depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2 verify return:1 depth=1 C = US, O = HydrantID (Avalanche Cloud Corporation), CN = HydrantID SSL ICA G2 verify return:1 depth=0 C = US, ST = CA, L = San Jose, O = "Cisco Systems, Inc.", CN = msesandbox.cisco.com verify return:1 ... Start Time: 1420616960 Timeout : 300 (sec) Verify return code: 0 (ok) 

注意OpenSSL用Verify return code: 0 (ok)完成Verify return code: 0 (ok) 。 这告诉你你有一个很好的链条。 OpenSSL不执行主机名匹配,但我们已经知道证书中的主机名是好的。


现在,对于Ruby代码。 您需要做的就是将CA插入Ruby:

 #!/usr/bin/ruby require 'net/http' require 'net/https' require 'openssl' uri = URI('https://msesandbox.cisco.com:443') options_mask = OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 | OpenSSL::SSL::OP_NO_COMPRESSION http = Net::HTTP.new(uri.host, uri.port) request = Net::HTTP::Get.new(uri.request_uri) if uri.scheme == "https" http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.ca_file = File.join(File.dirname(__FILE__), "quovadis-ca.pem") # http.ssl_options = options_mask end response = http.request request 

这是一个运行:

 $ ./Connect-Test.rb $ 

没有例外,也没有OpenSSL::SSL::VERIFY_NONE

您应该尝试使用options_mask因为它会删除弱/受伤/损坏的协议。 但Ruby有时会如此破碎和无证,我从来没有能够让它发挥作用。


我能够信任HydrantID SSL ICA G2QuoVadis Root CA2 G3和OpenSSL(意味着我从OpenSSL获得了Verify Result 0 (OK) )。 但Ruby只能处理QuoVadis Root CA2 G3 (它无法建立连接到HydrantID SSL ICA G2 )。 更多Ruby破坏。

如果您使用浏览器访问主机,例如

 > https://64.103.26.61/ 

你会看到你会得到同样的错误。 此服务器上的证书无效,因为服务器响应的另一个主机名不是证书中写入的主机名。

如果在Digicert Helpcenter中输入服务器地址,则可以查找更复杂的描述。 证书已发给msesandbox.cisco.com 。 如果这是您尝试访问的地址,请使用此地址而不是IP。 如果这是您的服务器,请更改响应名称

好的,我找到了解决方案。 我刚刚添加了以下代码,一切都解决了。 我认为问题是思科服务器。

 :verify_ssl => OpenSSL::SSL::VERIFY_NONE