一台服务器上是否存在Java SSLHandshakeException,而另一台服务器上没有?

雷蒙德·奥尔金(Raymond Holguin)

为了调试最近在我们的一台服务器上出现的SSL问题,我编写了一个非常简单的程序来连接到我们Intranet中的SSL站点。

    URL authURL = null;
    BufferedReader br = null;
    String url = "https://our.server:443";

    try {
        authURL = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) 
                authURL.openConnection(); 
        conn.setDoOutput(false);
        conn.setDoInput(true);
        conn.setAllowUserInteraction(false);
        conn.setUseCaches(false);
        conn.connect();
    } catch (MalformedURLException urlEx) {
        urlEx.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    } finally {
        if (br != null) {
            try { br.close(); }
            catch (IOException e) {}
        }//if
    }//finally

该代码在我们的一台服务器上失败,并出现SSLHandshakeException异常,但是相同的确切代码在另一台服务器上也可以正常工作。我运行了启用了SSL调试的程序,这是每个服务器的结果

工作服务器-SLES 11.3,Java IBM 1.6.0 64位

... no IV used for this cipher
main, WRITE: SSLv3 Change Cipher Spec, length = 1
JsseJCE:  Using cipher RC4 from provider TBD via init
CipherBox:  Using cipher RC4 from provider from init IBMJCE version 1.2
JsseJCE:  Using MAC SslMacSHA1 from provider TBD via init
MAC:  Using MessageDigest SslMacSHA1 from provider IBMJCE version 1.2
*** Finished
verify_data:  { 101, 62, 81, 35, 

13, 178, 124, 13, 43, 0, 5, 248, 32, 15, 39, 244, 97, 96, 98, 227, 1 8, 172, 226, 53, 71, 218, 210, 21, 72, 85, 44, 130, 175, 194, 228, 34 }
***
main, WRITE: SSLv3 Handshake, length = 60
main, READ: SSLv3 Change Cipher Spec, length = 1
JsseJCE:  Using cipher RC4 from provider TBD via init
CipherBox:  Using cipher RC4 from provider from init IBMJCE version 1.2
JsseJCE:  Using MAC SslMacSHA1 from provider TBD via init
MAC:  Using MessageDigest SslMacSHA1 from provider IBMJCE version 1.2
main, READ: SSLv3 Handshake, length = 60
*** Finished
verify_data:  { 160, 27, 2, 24, 10, 15, 205, 204, 241, 225, 183, 150, 243, 244, 43, 107, 40, 112, 173  42, 122, 139, 225, 16, 33, 168, 255, 184, 23, 18, 69, 103, 19, 68, 182, 139 }
***
cached session [Session-1, SSL_RSA_WITH_RC4_128_SHA]
%% Cached client session: [Session-1, SSL_RSA_WITH_RC4_128_SHA]
main, WRITE: SSLv3 Application Data, length = 213
main, READ: SSLv3 Application Data, length = 402

无法使用的服务器:Windows 7,Java JDK 1.6.0_39

   ... no IV used for this cipher
main, WRITE: SSLv3 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 235, 130, 222, 201, 56, 225, 104, 77, 87, 210, 63, 16, 196, 223, 123, 231, 173, 146, 111, 102, 99, 214, 20, 244, 138, 79, 217, 140, 10, 61, 167, 9, 222, 95, 247, 208 }
***
main, WRITE: SSLv3 Handshake, length = 60
main, received EOFException: error
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
main, SEND SSLv3 ALERT:  fatal, description = handshake_failure
main, WRITE: SSLv3 Alert, length = 22
main, called closeSocket()
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:882)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1203)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1230)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1214)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)
    at test.Main.main(Main.java:43)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:333)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:863)
    ... 7 more

是否有人对我可以在Windows 7机器上运行此简单代码的方法有任何想法?我整天都在这里,在这一点上很迷路。谢谢你的帮助!

更新-请求的openssl输出

工作服务器

CONNECTED(00000003)
depth=3 /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
verify return:1
depth=2 /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
verify return:1
depth=1 /C=US/O=Thawte, Inc./CN=Thawte SGC CA - G2
verify return:1
depth=0 /C=US/ST=California/L=Riverside/O=University of California-Riverside/OU=Computing and Communication/CN=example.com
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=Riverside/O=University of California-Riverside/OU=Computing and Communication/CN=example.com
   i:/C=US/O=Thawte, Inc./CN=Thawte SGC CA - G2
 1 s:/C=US/O=Thawte, Inc./CN=Thawte SGC CA - G2
   i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
 2 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
 3 s:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
---

伺服器无法运作

    CONNECTED(0000018C)
depth=3 C = US, O = "VeriSign, Inc.", OU = Class 3 Public Primary Certification
Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Riverside/O=University of California-Riverside/OU=Computing and Communication/CN=example.com
   i:/C=US/O=Thawte, Inc./CN=Thawte SGC CA - G2
 1 s:/C=US/O=Thawte, Inc./CN=Thawte SGC CA - G2
   i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc.
 - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
 2 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc.
 - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
 3 s:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
---
w

结果可能会有所不同,因为每台计算机上的信任库都略有不同。在这里,我假设您正在服务器上本地运行客户端,因此每个客户端都使用本地可用的JVM。

但这并不能解释看起来奇怪的链条...

 0 s:/C=US/ST=California/L=Riverside/O=University of California-Riverside/OU=Computing and Communication/CN=example.com
   i:/C=US/O=Thawte, Inc./CN=Thawte SGC CA - G2
 1 s:/C=US/O=Thawte, Inc./CN=Thawte SGC CA - G2
   i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc.
 - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
 2 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc.
 - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
 3 s:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority

证书0是服务器的证书,显然必须存在。

证书1是构建链所需的中介。服务器也必须发送它。它必须发送它以避免“哪个目录”问题这是PKI中的一个众所周知的问题,这意味着客户端不知道缺少证书时应转到哪个目录。

我在Thawte根证书中找不到证书1 证书1的颁发者为VeriSign Class 3 Public Primary Certification Authority - G5

证书2是VeriSign Class 3 Public Primary Certification Authority - G5根据经验,我知道这是一个CA,而且我不确定为什么它声称拥有发行人。

您可以VeriSign Class 3 Public Primary Certification Authority - G5Verisign根证书下载文件名是VeriSign-Class-3-Public-Primary-Certification-Authority-G5.pem然后:

$ openssl x509 -in VeriSign-Class-3-Public-Primary-Certification-Authority-G5.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            18:da:d1:9e:26:7d:e8:bb:4a:21:58:cd:cc:6b:3b:4a
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
        Validity
            Not Before: Nov  8 00:00:00 2006 GMT
            Not After : Jul 16 23:59:59 2036 GMT
        Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
                    ...
                    25:15
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            1.3.6.1.5.5.7.1.12: 
                0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
            X509v3 Subject Key Identifier: 
                7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
    Signature Algorithm: sha1WithRSAEncryption
         93:24:4a:30:5f:62:cf:d8:1a:98:2f:3d:ea:dc:99:2d:bd:77:
         ...
         a8:ed:63:6a

注意它的CA:主题和发行者是相同的,存在CA:true标记为严重的基本约束等。

因此,我认为您可能正在使用旧的Verisign证书。它甚至可能已过期。但是您可以访问它,所以只有您可以说出来。

现在,这里确实很奇怪:证书3和Class 3 Public Primary Certification Authority它也是一个CA,但没有任何认证。

因此,我将执行以下操作:

  1. 从链中删除证书2
  2. 从链中删除证书3
  3. 添加VeriSign Class 3 Public Primary Certification Authority - G5到信任库
  4. 使用OpenSSL测试两个服务器

要测试:首先,VeriSign Class 3 Public Primary Certification Authority - G5Verisign根证书下载文件名是VeriSign-Class-3-Public-Primary-Certification-Authority-G5.pem

openssl s_client在每个服务器上第二次运行(命令如下所示)。包括CAfile用于指定Verisign信任锚选项。使用所需的信任锚,其结尾应为:Verify return code: 0 (ok)

$ openssl s_client -connect example.com:443 -CAfile VeriSign-Class-3-Public-Primary-Certification-Authority-G5.pem
...
Start Time: 1407273676
Timeout   : 300 (sec)
Verify return code: 0 (ok)

openssl s_client将从循环中删除Java,并允许您确认自己具有“已知良好”的基线,可以进一步在Java中进行测试。但是我怀疑您在行为异常的服务器的证书存储中有一个旧的Verisign根,或者在行为异常的服务器的证书存储中缺少了必需的根,或者两者都缺少。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

一台服务器,另一台PC上的多个网站

AJAX等到文件在另一台服务器上存在

文件上传并保存在另一台服务器 PHP 上

如何在一台服务器上使用GitLab并将所有存储库存储在另一台服务器上?

关于服务器,何时应该将进程移至另一台服务器而不是同一台服务器上?

网络C#上另一台服务器上的引用路径

Laravel API 没有从另一台服务器读取访问令牌

我可以将一台服务器上的stdout传送到另一台服务器上的stdin吗?

如何从一台服务器上的水壶作业在另一台服务器上运行Shell脚本?

授予一台服务器上的IIS对另一台服务器上的文件夹的读取访问权限

htaccess在一台服务器上正常工作,并导致另一台服务器上的重定向循环

一台服务器上的远程容器正常工作,另一台服务器上的远程容器不工作

SOAP请求在一台服务器上随机失败,但在iOS7上的另一台服务器上工作

如何使用ssh从一台服务器上的文件复制文本并追加到另一台服务器上的文件?

Imagick 功能可在一台服务器上运行,但不能在另一台服务器上运行

用于从另一台服务器上的 Elasticsearch 获取数据的 PHP 脚本

在另一台服务器上的Spring Boot外部配置

Ansible 命令触发在另一台服务器上的注册

Flask在另一台服务器上时在本地查找db

如何导入在另一台服务器上创建的状态?

Node.js处理另一台服务器上的登录

另一台服务器上的git分支

使用位于另一台服务器上的PHP文件

在另一台服务器上设置的 PHP 会话

高频率在另一台服务器上运行脚本

如何连接在另一台服务器上运行的网络

Discord - 与另一台服务器上的机器人聊天

如何在另一台服务器上运行 TestCafe

从 JSON API(从一台服务器)获取数据并将其显示在 HTML 上(到另一台服务器)