Tomcat 7 个 Web 应用程序获得 SSL handshake_failure,桌面应用程序没有

Tomcat 7 Web App gets SSL handshake_failure, desktop application doesn't

大家好, 我的 Web 应用程序出现 HTTPS 连接问题,导致 handshake_failure.

为了排除故障,我编写了一个简单的桌面应用程序,其参数与网络应用程序中使用的参数相同。

这是桌面应用程序的源代码:

public class Main {
    private final static String helperMsg = "java -jar SSLTest.jar url";

    public static void main(String[] args) {
        System.setProperty("https.protocols", "TLSv1.2,TLSv1.1");

        if(args.length < 1){
            System.out.println("Insufficient arguments: " + args.length);
            System.out.println(helperMsg);
            return;
        }
        String httpsTarget = args[0];
        URL url;
        try {
            url = new URL(httpsTarget);
            HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
            if(connection == null)
                throw new IOException("Connection null");

            SSLSocketFactoryEx factory = new SSLSocketFactoryEx(null,null,null);
            connection.setSSLSocketFactory(factory);

            connection.setRequestMethod("GET");
            connection.connect();
            System.out.println(connection.getResponseCode() + ": " + connection.getResponseMessage());
        } catch (Exception e) {
            System.out.println("Exception: " + e.getMessage());
        }
    }
}

SSLSocketFactoryEx 来自 this post.

将这个简单的应用程序打包到可执行 JAR 文件并将所需的证书安装到我的信任库后,我的启动命令如下:

java -Djavax.net.ssl.trustStore=<trustStoreFile> -Djavax.net.debug=all -jar SSLTest.jar <httpsURL>

在 Web 应用程序内部,HTTPS 连接命令完全相同,但是 桌面应用程序成功获得 HTTP 响应,Web 应用程序卡在 handshake_failure,就像使用桌面应用程序时一样,我没有通过 System.setProperty("https.protocols", "TLSv1.2,TLSv1.1") 指令指定默认使用 TLSv1.2 或 TLSv1.1,也没有使用 SSLSocketFactoryEx 作为自定义 SSLSocketFactory 对于 HttpsURLConnection.

这就是为什么我将错误归咎于 Tomcat 配置,但我不明白是什么。

我的 Tomcat Java 选项已经包含以下 VM 参数:

-Djavax.net.ssl.trustStore=<trustStoreFile>
-Dhttps.protocols=TLSv1.2,TLSv1.1
-Djavax.net.debug=all

我的 server.xml 包含以下字段:

<Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
        keystoreFile=<keyStoreFile> keystorePass=<keyStorePW>
        truststoreFile=<trustStoreFile> truststorePass=<trustStorePW>
        sslEnabledProtocols="TLSv1.2,TLSv1.1"
        redirectPort="8443" />

我还尝试通过说明在 Web 应用程序中设置 keystoreFilekeystorePasstruststoreFiletruststorePass 属性以及 protocols 属性,完全没有结果,仍然得到 handshake_failure.

我正在使用 Tomcat 7.0.59 和 jdk1.7。0_80 我无法更新任何东西。

感谢您的努力。

-- 编辑--

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
http-apr-80-exec-47, called close()
http-apr-80-exec-47, called closeInternal(true)
http-apr-80-exec-47, called closeSocket(selfInitiated)
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
DOPO CHIAMATA 3
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1531997568 bytes = { 145, 51, 114, 234, 178, 6, 227, 30, 223, 175, 233, 64, 136, 117, 68, 227, 252, 207, 144, 188, 113, 85, 202, 197, 214, 163, 225, 65 }
Session ID:  {}
Cipher Suites: [TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
Extension server_name, server_name: [host_name: <hotsname>]
***
[write] MD5 and SHA1 hashes:  len = 140
0000: 01 00 00 88 03 03 5B 50   6E 80 91 33 72 EA B2 06  ......[Pn..3r...
0010: E3 1E DF AF E9 40 88 75   44 E3 FC CF 90 BC 71 55  .....@.uD.....qU
0020: CA C5 D6 A3 E1 41 00 00   10 00 6A 00 33 00 32 00  .....A....j.3.2.
0030: 3D 00 35 00 3C 00 2F 00   FF 01 00 00 4F 00 0D 00  =.5.<./.....O...
0040: 1A 00 18 06 03 06 01 05   03 05 01 04 03 04 01 03  ................
0050: 03 03 01 02 03 02 01 02   02 01 01 00 00 00 2D 00  ..............-.
0060: 2B 00 00 28 63 6F 6C 6C   70 72 6F 78 79 6F 75 74  +..(XXXXXXXXXXX
0070: 2E 77 68 6F 6C 65 73 61   6C 65 2E 74 65 6C 65 63  XXXXXXXXXXXXXXX
0080: 6F 6D 69 74 61 6C 69 61   2E 63 6F 6D              XXXXXXXXXXXX
http-apr-80-exec-47, WRITE: TLSv1.2 Handshake, length = 140
[Raw write]: length = 145
0000: 16 03 03 00 8C 01 00 00   88 03 03 5B 50 6E 80 91  ...........[Pn..
0010: 33 72 EA B2 06 E3 1E DF   AF E9 40 88 75 44 E3 FC  3r........@.uD..
0020: CF 90 BC 71 55 CA C5 D6   A3 E1 41 00 00 10 00 6A  ...qU.....A....j
0030: 00 33 00 32 00 3D 00 35   00 3C 00 2F 00 FF 01 00  .3.2.=.5.<./....
0040: 00 4F 00 0D 00 1A 00 18   06 03 06 01 05 03 05 01  .O..............
0050: 04 03 04 01 03 03 03 01   02 03 02 01 02 02 01 01  ................
0060: 00 00 00 2D 00 2B 00 00   28 63 6F 6C 6C 70 72 6F  ...-.+..(XXXXXX
0070: 78 79 6F 75 74 2E 77 68   6F 6C 65 73 61 6C 65 2E  XXXXXXXXXXXXXXX
0080: 74 65 6C 65 63 6F 6D 69   74 61 6C 69 61 2E 63 6F  XXXXXXXXXXXXXXX
0090: 6D                                                 XXXXX
[Raw read]: length = 5
0000: 15 03 03 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
http-apr-80-exec-47, READ: TLSv1.2 Alert, length = 2
http-apr-80-exec-47, RECV TLSv1 ALERT:  fatal, handshake_failure
http-apr-80-exec-47, called closeSocket()
http-apr-80-exec-47, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Received fatal alert: handshake_failure

唯一可行的选择是 运行 Tomcat 在更新的 jvm.dll 上,它修复了自 jre 1.7.0_131-b31 以来的 SSL 错误 默认启用 TLSv1.1 和 TLSv1.2。