JDK 1.5 SSLHandshakeException

Posted

技术标签:

【中文标题】JDK 1.5 SSLHandshakeException【英文标题】: 【发布时间】:2016-06-03 15:35:23 【问题描述】:

我有一个奇怪的问题,我无法解决。

我有 JDK 1.5 版本和基于 SSL 的套接字通信,只需发送和接收字符串数据。

try 

    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(new FileInputStream(
            "path_to_.jks"),
            "secret_of_jks".toCharArray());

    TrustManagerFactory tmf = TrustManagerFactory
            .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);
    KeyManagerFactory kmf = KeyManagerFactory
            .getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(ks, "secret_of_jks".toCharArray());
    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    Socket s = ctx.getSocketFactory().createSocket("address_of_server", PORT);

    String jsonEx = "json text to send server";
    StringBuilder sb = new StringBuilder();
    sb.append(jsonEx.getBytes().length);
    sb.append("\r\n");
    sb.append(jsonEx);


    PrintWriter writer = new PrintWriter(s.getOutputStream(), true);
    writer.println(sb.toString());
    BufferedReader in =  new BufferedReader(new InputStreamReader(s.getInputStream()));
    System.out.println(in.readLine());
    writer.flush();
 catch (Exception e) 
    e.printStackTrace();

当我使用 JDK 1.7+ 时,一切正常,但是当我切换到 1.6- 时,它会抛出 javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

我的证书是 2048 加密的,我还安装了 JCE Unlimited Strength Jurisdiction Policy http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

如果有人感兴趣,这里是完整的例外:

javax.net.ssl.SSLException:连接已关闭: javax.net.ssl.SSLHandshakeException:远程主机关闭连接 在握手期间 com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1154) 在 com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:65) 在 sun.nio.cs.StreamDecoder$CharsetSD.readBytes(StreamDecoder.java:411) 在 sun.nio.cs.StreamDecoder$CharsetSD.implRead(StreamDecoder.java:453) 在 sun.nio.cs.StreamDecoder.read(StreamDecoder.java:183) 在 java.io.InputStreamReader.read(InputStreamReader.java:167) 在 java.io.BufferedReader.fill(BufferedReader.java:136) 在 java.io.BufferedReader.readLine(BufferedReader.java:299) 在 java.io.BufferedReader.readLine(BufferedReader.java:362) 在 ConnectorTest.main(ConnectorTest.java:45) 原因: javax.net.ssl.SSLHandshakeException:远程主机关闭连接 在握手期间 com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:739) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1025) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:619) 在 com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59) 在 sun.nio.cs.StreamEncoder$CharsetSE.writeBytes(StreamEncoder.java:336) 在 sun.nio.cs.StreamEncoder$CharsetSE.implFlushBuffer(StreamEncoder.java:404) 在 sun.nio.cs.StreamEncoder$CharsetSE.implFlush(StreamEncoder.java:408) 在 sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:152) 在 java.io.OutputStreamWriter.flush(OutputStreamWriter.java:213) 在 java.io.BufferedWriter.flush(BufferedWriter.java:236) 在 java.io.PrintWriter.newLine(PrintWriter.java:410) 在 java.io.PrintWriter.println(PrintWriter.java:559) 在 java.io.PrintWriter.println(PrintWriter.java:670) 在 ConnectorTest.main(ConnectorTest.java:43) 原因: java.io.EOFException:SSL 对等点在 com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:321) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:720) ... 13 更多

ConnectorTest Line 43 is

System.out.println(in.readLine());

更新

trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1439443814 bytes =  228, 36, 73, 128, 109, 225, 11, 36, 62, 40, 147, 150, 27, 145, 150, 163, 244, 28, 97, 56, 188, 81, 117, 31, 235, 60, 101, 224 
Session ID:  
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:   0 
***
main, WRITE: TLSv1 Handshake, length = 75
main, WRITE: SSLv2 client hello message, length = 101
main, received EOFException: error
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
main, SEND TLSv1 ALERT:  fatal, description = handshake_failure
main, WRITE: TLSv1 Alert, length = 2
main, called closeSocket()

更新 2

我刚刚发现,它们之间的区别是:

有效期为 2 月 16 日星期二 20:07:36 GET 2016 至 2 月 16 日星期四 20:07:36 GET 2017 1.7 正确

有效期为 2 月 16 日星期二 16:07:36 GMT 2016 至 2 月 16 日星期四 16:07:36 GMT 2017 1.6 错误

【问题讨论】:

您可以查看此链接,不是解决方案,而是一些见解:***.com/questions/21245796/… 【参考方案1】:

经过大量研究,我发现没有办法做到这一点,当然,安装无限策略也是丑陋的解决方案。 Sun 不建议我们更改政策。解决这个问题的最好方法是,始终保持你的 Java 版本比这个更好。我不得不写 1.5 并且没有其他机会简单地升级系统并决定更糟糕但唯一的解决方案当然有效。我用 Java 1.8 + Wildlfy 8.2 在同一台机器上用不同的 Jboss 端口创建了某种代理服务,并从那里调用服务。 1.5 和 1.8 应用程序使用简单的肥皂协议进行通信。问题“已解决”。

【讨论】:

【参考方案2】:

可能是服务器不支持客户端的 SSL 版本(客户端提供的 SSL 版本太低)。

尝试添加系统属性“javax.net.debug=ssl”,以便在系统输出中获得更好的错误描述。例如:

System.setProperty("javax.net.debug", "ssl");

或添加命令行参数:

-Djavax.net.debug=ssl

为什么要使用较旧的 Java?如果您必须使用 1.6,请尝试将其更新到最新的补丁版本。

【讨论】:

我必须使用旧版本,但如果我将它更新到 1.6 则没有理由,它只适用于 Java 1.7 +。我用我的问题编辑了调试日志。 检查这个:***.com/questions/9828414/…

以上是关于JDK 1.5 SSLHandshakeException的主要内容,如果未能解决你的问题,请参考以下文章

Maven 项目生成或者update jdk变为1.5的问题

解决idea中maven默认jdk为1.5的问题 : IntelliJ IDEA 源值1.5已过时,将在未来所有版本中删除

JDK 1.5新特性

jdk 1.5 1.6 1.7 加入新特性

解决maven update project 后项目jdk变成1.5的问题

原创Mac OS X 下同时安装多个版本的JDK(JDK 1.5 ~ JDK 1.8)