使用 Java 8,服务器仅支持 TLSv1
,无法从 cent OS 建立安全套接字连接
With Java 8, server which only supports TLSv1
, it fails to make secure socket connection from cent OS
版本
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
来源
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Created by jigar.joshi on 6/10/15.
*/
public class SSLTester {
public static void main(String[] args) throws Exception {
SSLSocketFactory f =
(SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) f.createSocket("efm.sandbox.vovici.com", 443 );
try {
printSocketInfo(socket);
socket.startHandshake();
System.out.println("----------------------------------SUCCESS----------------------------------");
BufferedReader r = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String m = null;
while ((m = r.readLine()) != null) {
System.out.println(m);
}
r.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
System.err.println(e.toString());
}
}
private static void printSocketInfo(SSLSocket s) {
System.out.println("Socket class: " + s.getClass());
System.out.println(" Remote address = "
+ s.getInetAddress().toString());
System.out.println(" Remote port = " + s.getPort());
System.out.println(" Local socket address = "
+ s.getLocalSocketAddress().toString());
System.out.println(" Local address = "
+ s.getLocalAddress().toString());
System.out.println(" Local port = " + s.getLocalPort());
System.out.println(" Need client authentication = "
+ s.getNeedClientAuth());
SSLSession ss = s.getSession();
System.out.println(" Cipher suite = " + ss.getCipherSuite());
System.out.println(" Protocol = " + ss.getProtocol());
}
}
使用相同版本的JVM,在OSX上握手成功,在centOS上失败,失败原因是它只尝试使用TLSv1.2
(JVM 8默认)并且没有尝试底层协议
With same version of JVM, it makes handshake successfully on OSX, it fails on centOS, Failure reason is it only tries to use TLSv1.2
(default in JVM 8) and doesn't try lower protocol
调试说明:
-Ddeployment.security.TLSv1.0=true
-Ddeployment.security.TLSv1=true
-Ddeployment.security.TLSv1.1=false
-Ddeployment.security.TLSv1.2=false
-Djavax.net.debug=ssl:handshake:verbose
问题:
为什么在 OSX 上可以选择 TLSv1
而在 CentOS 上却不行?
Why it is able to choose TLSv1
on OSX and not on CentOS?
我如何告诉 JVM 以特定顺序使用协议,或者如果它考虑按版本排序,那么我如何告诉它也尝试使用 v1
How can I tell JVM to use protocols in specific order or if it considers order by the version then how can I tell it to also try with v1
我在 JRE 中安装了无限强度的 JCE 策略,这导致了这种情况,没有它就可以工作,所以 OSX 和 CentOS 的区别就消失了,我怎样才能让它工作?
I have unlimited strength JCE policies installed with JRE that is causing this, it works without that so OSX and CentOS difference is gone, How can I still make it work ?
输出
Socket class: class sun.security.ssl.SSLSocketImpl
Remote address = efm.sandbox.vovici.com/206.132.29.15
Remote port = 443
Local socket address = /10.10.152.143:50376
Local address = /10.10.152.143
Local port = 50376
Need client authentication = false
Cipher suite = SSL_NULL_WITH_NULL_NULL
Protocol = NONE
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1529)
at sun.security.ssl.SSLSocketImpl.checkWrite(SSLSocketImpl.java:1541)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
at SSLTester.main(SSLTester.java:24)
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:980)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
at sun.security.ssl.SSLSocketImpl.getSession(SSLSocketImpl.java:2225)
at SSLTester.printSocketInfo(SSLTester.java:56)
at SSLTester.main(SSLTester.java:23)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(InputRecord.java:505)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:961)
... 5 more
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
尝试将协议限制为 TLSv1
使用:
Try limiting the protocols to just TLSv1
using:
-Djdk.tls.client.protocols=TLSv1
有关详细信息,请参阅此页面:https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2
See this page for more details: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2
希望这会有所帮助,
尤里
这篇关于Java 8、JCE 无限强度策略和基于 TLS 的 SSL 握手的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!