Java 7的SSL连接失败 [英] SSL connection failing for Java 7

查看:120
本文介绍了Java 7的SSL连接失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Java 7创建与远程服务器的SSL连接,并且我收到以下异常:

I am attempting to create an SSL connection to a remote server using Java 7 and I'm receiving the following exception:

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
    at java.io.BufferedWriter.flush(BufferedWriter.java:254)
    at ssl7.Client.main(Client.java:22)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(InputRecord.java:482)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)

当我使用Java 6重新运行代码时,没有例外。我在StackOverflow的其他地方找到了对这个问题的引用,但我的情况有一个转折。使用Java 7失败的客户端代码是

When I rerun the code using Java 6, there is no exception. I have found references to this problem elsewhere on StackOverflow but my situation comes with a twist. The client code, which fails with Java 7 is

public class Client {

    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        try {
            SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("login.solon.com", 443);    
            OutputStream outputstream = sslsocket.getOutputStream();
            OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
            BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);
                bufferedwriter.write("hello\n");
                bufferedwriter.flush();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

当我添加行

sslsocket.setEnabledCipherSuites(new String[] {"SSL_RSA_WITH_RC4_128_MD5"});

创建套接字后,它可以正常工作。

after creating the socket, it works.

现在, SSL_RSA_WITH_RC4_128_MD5 存在于原始的密码套件集中,所以我所做的就是添加限制。从长远来看,限制密码套件不是一个可行的解决方案。谁能解释一下这里发生了什么?

now, SSL_RSA_WITH_RC4_128_MD5 exists in the original set of cipher suites so all I've done is add restrictions. Restricting the cipher suites is not a viable solution in the long run. Can anyone explain what is going on here?

完整的调试日志是:

keyStore is : 
keyStore type is : jks
keyStore provider is : 
init keystore
init keymanager of type SunX509
trustStore is: C:\Temp\keystore\clientkeystore
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
  Subject: CN=W, OU=D, O=S, L=H, ST=I, C=IL
  Issuer:  CN=W, OU=D, O=S, L=H, ST=I, C=IL
  Algorithm: DSA; Serial number: 0x4a6e05b7
  Valid from Mon Oct 07 10:22:54 EEST 2013 until Sun Jan 05 09:22:54 EET 2014

adding as trusted cert:
  Subject: CN=login.solon.com, OU=Domain Validated, OU=Thawte SSL123 certificate, OU=Go to https://www.thawte.com/repository/index.html
  Issuer:  CN=Thawte DV SSL CA, OU=Domain Validated SSL, O="Thawte, Inc.", C=US
  Algorithm: RSA; Serial number: 0x3012ec22473f20aa2cdc4bf7fe2d22f4
  Valid from Wed Feb 13 02:00:00 EET 2013 until Thu Apr 14 02:59:59 EEST 2016

adding as trusted cert:
  Subject: CN=W, OU=D, O=S, L=H, ST=I, C=IL
  Issuer:  CN=W, OU=D, O=S, L=H, ST=I, C=IL
  Algorithm: RSA; Serial number: 0x5864235a
  Valid from Mon Oct 07 10:28:06 EEST 2013 until Sun Jan 05 09:28:06 EET 2014

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_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 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 unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_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 unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
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 unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Allow unsafe renegotiation: true
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1381093608 bytes = { 221, 239, 107, 239, 150, 213, 224, 210, 101, 229, 42, 58, 92, 9, 151, 0, 128, 105, 0, 55, 53, 224, 90, 111, 130, 175, 61, 121 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_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_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
[write] MD5 and SHA1 hashes:  len = 149
0000: 01 00 00 91 03 01 52 52   D1 E8 DD EF 6B EF 96 D5  ......RR....k...
0010: E0 D2 65 E5 2A 3A 5C 09   97 00 80 69 00 37 35 E0  ..e.*:\....i.75.
0020: 5A 6F 82 AF 3D 79 00 00   2A C0 09 C0 13 00 2F C0  Zo..=y..*...../.
0030: 04 C0 0E 00 33 00 32 C0   07 C0 11 00 05 C0 02 C0  ....3.2.........
0040: 0C C0 08 C0 12 00 0A C0   03 C0 0D 00 16 00 13 00  ................
0050: 04 00 FF 01 00 00 3E 00   0A 00 34 00 32 00 17 00  ......>...4.2...
0060: 01 00 03 00 13 00 15 00   06 00 07 00 09 00 0A 00  ................
0070: 18 00 0B 00 0C 00 19 00   0D 00 0E 00 0F 00 10 00  ................
0080: 11 00 02 00 12 00 04 00   05 00 14 00 08 00 16 00  ................
0090: 0B 00 02 01 00                                     .....
main, WRITE: TLSv1 Handshake, length = 149
[Raw write]: length = 154
0000: 16 03 01 00 95 01 00 00   91 03 01 52 52 D1 E8 DD  ...........RR...
0010: EF 6B EF 96 D5 E0 D2 65   E5 2A 3A 5C 09 97 00 80  .k.....e.*:\....
0020: 69 00 37 35 E0 5A 6F 82   AF 3D 79 00 00 2A C0 09  i.75.Zo..=y..*..
0030: C0 13 00 2F C0 04 C0 0E   00 33 00 32 C0 07 C0 11  .../.....3.2....
0040: 00 05 C0 02 C0 0C C0 08   C0 12 00 0A C0 03 C0 0D  ................
0050: 00 16 00 13 00 04 00 FF   01 00 00 3E 00 0A 00 34  ...........>...4
0060: 00 32 00 17 00 01 00 03   00 13 00 15 00 06 00 07  .2..............
0070: 00 09 00 0A 00 18 00 0B   00 0C 00 19 00 0D 00 0E  ................
0080: 00 0F 00 10 00 11 00 02   00 12 00 04 00 05 00 14  ................
0090: 00 08 00 16 00 0B 00 02   01 00                    ..........
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
[Raw write]: length = 7
0000: 15 03 01 00 02 02 28                               ......(
main, called closeSocket()
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
    at java.io.BufferedWriter.flush(BufferedWriter.java:254)
    at ssl7.Client.main(Client.java:22)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(InputRecord.java:482)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
    ... 10 more

谢谢。

解决方案

在使用运行基于Java的服务器的Ubuntu 12.04服务器使用其OpenJDK软件包之前,我已经看到过这种问题。 (这可能已修补,因为我无法重现最新更新的问题,但我的配置可能略有不同,我不记得。)

I have seen this sort of problem before when using an Ubuntu 12.04 server running a Java-based server using its OpenJDK package. (This may have been patched since, as I'm unable to reproduce the problem with the latest updates, but my configuration might be slightly different, I can't remember.)

这基本上是此Ubuntu问题中描述的问题。

This was essentially the problem described in this Ubuntu issue.

服务器端的EC计算基本上存在问题,导致连接无法正确建立。

There was essentially an issue with the EC calculation on the server side, which prevented the connection to be established correctly.

Java 6 <之间的密码套件的首选顺序有所不同/ a>和 Java 7 (参见两个表)。

因为 TLS_RSA_WITH_AES_128_CBC_SHA 高于Java 6中优先顺序中的任何EC密码套件(并且均由两者支持)客户端和服务器),当您与Java 6客户端连接时将选择它。

Because TLS_RSA_WITH_AES_128_CBC_SHA is higher than any EC cipher suite in the preference order in Java 6 (and supported by both client and server), it will be chosen when you connect with a Java 6 client.

当您连接Java 7客户端时,某些EC密码套件(例如,将选择 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA )服务器将开始继续此操作(您需要查看在服务器端握手调试日志以确认这一点)。然后服务器将使用密码套件选择过程完成,但由于尝试使用此密码套件时出现后续错误,因此无法继续使用。

When you connect with a Java 7 client, some EC cipher suites (e.g. TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA or TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) will be chosen and the server will start to proceed with this (you'd need to see the handshake debug log on the server side to confirm this). The server would then be done with the cipher suite selection process, but fail to go any further because of a subsequent bug when trying to use this cipher suite.

如果您有一些控制服务器(如果它确实运行基于Java的服务器),尝试升级到最新的JRE包。您还可以尝试Ubuntu问题中建议的修复(特别是如果它不使用PKCS#11)或者在服务器配置中禁用ECDHE密码套件。

If you have some control over the server (and if it's indeed running a Java-based server), try to upgrade to the latest JRE packages. You can also try the fixes suggested in the Ubuntu issue (especially if it's not using PKCS#11) or to disable the ECDHE cipher suites in the server configuration.

这篇关于Java 7的SSL连接失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆