Java 8,JCE无限强度策略和TLS上的SSL握手
对于仅支持TLSv1
Java 8服务器,它无法通过TLSv1
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上成功握手,在TLSv1.2
上失败,失败的原因是它只尝试使用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上而不是在CentOS上选择
TLSv1
? -
如何告诉JVM按特定顺序使用协议,或者如果它按版本考虑顺序,那么我怎么能告诉它也尝试使用
v1
编辑:
我有无限强度JCE策略与JRE一起安装,导致这种情况,没有这个,所以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
希望这可以帮助,
尤里