Java 7的SSL连接失败
我试图使用Java 7创建到远程服务器的SSL连接,但收到以下异常:Java 7的SSL连接失败,java,ssl,Java,Ssl,我试图使用Java 7创建到远程服务器的SSL连接,但收到以下异常: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946) at sun.security.ssl.SSLSocketImpl.performInitialHandsh
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)
当我使用Java6重新运行代码时,没有异常。我在StackOverflow上的其他地方找到了这个问题的参考资料,但我的情况有点扭曲。Java 7失败的客户端代码是
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"});
创建套接字之后,它就可以工作了
现在,SSL\u RSA\u WITH\u RC4\u 128\u MD5
存在于原始密码套件集中,所以我所做的就是添加限制。从长远来看,限制密码套件不是一个可行的解决方案。有人能解释一下这是怎么回事吗
完整调试日志为:
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 -Djavax.net.ssl.trustStore=${resources}/localhost.truststore \
-Djavax.net.ssl.trustStorePassword=TRUSTSTORE_PASSWORD -jar client.jar com.acme.RunClient
将服务器配置()与Java7中的可用密码套件列表进行比较,您似乎只有两个可接受的密码套件选项:
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
现在,TLS\u DHE\u RSA\u WITH_AES\u 128\u CBC\u SHA
被认为是弱的,但是由于您的服务器没有声明对订单的偏好,它可能会选择此选项,然后握手失败。对于Java6,它完全有可能只是选择了一个更强大的套件。您为它提供的选项越多,您就越有机会选择弱密码,因此当您指定要使用的单个套件时,它就会成功。(虽然在查看您的服务器配置时,我不确定您是如何成功地获得SSL\u RSA\u WITH_RC4\u 128\u MD5,因为它显然不受支持。)按照这种思路,也许您应该尝试将密码套件限制为:
TLS_RSA_WITH_AES_128_CBC_SHA
或者更具体地说:
sslsocket.setEnabledCipherSuites(new String[] {"TLS_RSA_WITH_AES_128_CBC_SHA"});
这是Java7与密钥库的兼容性问题。将密钥库文件转换为.p12。使用它应该可以工作。我以前在使用Ubuntu12.04服务器运行基于Java的服务器时,使用OpenJDK包时遇到过这种问题。(这可能是因为我无法用最新的更新重现问题而修补的,但我的配置可能略有不同,我不记得了。) 这基本上就是中描述的问题 服务器端的EC计算基本上存在问题,这妨碍了正确建立连接 和之间的密码套件的首选顺序有所不同(请参见两个表) 由于
TLS\u RSA\u WITH_AES\u 128\u CBC\u SHA
高于Java 6中首选顺序中的任何EC密码套件(并且受客户端和服务器支持),因此在连接Java 6客户端时将选择它
当您与Java 7客户端连接时,将选择一些EC密码套件(例如TLS\u ECDHE\u RSA\u with_AES\u 128\u CBC\u SHA
或TLS\u ECDHE\u RSA\u with_AES\u 256\u CBC\u SHA
),服务器将开始执行此操作(您需要查看服务器端的握手调试日志以确认这一点)。然后,服务器将完成密码套件选择过程,但由于尝试使用此密码套件时出现后续错误,因此无法继续
如果您对服务器有一定的控制权(如果它确实运行基于Java的服务器),请尝试升级到最新的JRE包。您还可以尝试Ubuntu版本中建议的修复(特别是如果它不使用PKCS#11)或在服务器配置中禁用ECDHE密码套件。格式特别好的问题!坚持下去!也许您的代码需要更坚定的握手。我知道我用弱握手拒绝所有连接。您使用的是哪种特定的java版本?我在Java 1.7.0_21和1.6.0_25上运行了代码服务器正在运行1.7.0_21阅读问题。从追踪中可以明显看出他有一个信任库。无论如何,一个问题是不可能的。这是一个答案。你从哪里得到这个主意的?客户端没有密钥库。为什么DHE_RSA密码很弱?TLS_DHE_RSA_WITH_AES_128_CBC_SHA具有完美的前向保密性,TLS_RSA_WITH_AES_128_CBC_SHA没有,在其他方面也是一样的。为了回答我自己的评论,无论出于何种原因,Java 6和Java 7中的
SunJSSE
加密提供程序使用768位DH密钥,而且似乎没有办法改变它,这是一个遗憾,因为唯一的解决办法是禁用DHE套件。我很高兴您能够回答自己的评论,因为我不知道这一点。=)