Java 8、JCE 无限强度策略和 SSL Handshake over TLS
Java 8 , JCE Unlimited Strength Policy and SSL Handshake over TLS
使用Java 8,仅支持TLSv1
的服务器,无法从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) 并且不尝试更低的协议
调试说明:
-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上却不能?
我如何告诉 JVM 按特定顺序使用协议,或者如果它考虑按版本排序,那么我如何告诉它也尝试使用 v1
编辑:
我在 JRE 上安装了无限强度的 JCE 策略,这导致了这个问题,它可以在没有它的情况下工作,所以 OSX 和 CentOS 区别消失了,我怎样才能让它继续工作?
编辑:
输出
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
使用:
-Djdk.tls.client.protocols=TLSv1
有关详细信息,请参阅此页面:https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2
希望这对您有所帮助,
尤里
使用Java 8,仅支持TLSv1
的服务器,无法从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) 并且不尝试更低的协议
调试说明:
-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上却不能?我如何告诉 JVM 按特定顺序使用协议,或者如果它考虑按版本排序,那么我如何告诉它也尝试使用
v1
编辑:
我在 JRE 上安装了无限强度的 JCE 策略,这导致了这个问题,它可以在没有它的情况下工作,所以 OSX 和 CentOS 区别消失了,我怎样才能让它继续工作?
编辑:
输出
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
使用:
-Djdk.tls.client.protocols=TLSv1
有关详细信息,请参阅此页面:https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2
希望这对您有所帮助,
尤里