Java 8,JCE无限强度策略和SSL上的SSL握手 [英] Java 8 , JCE Unlimited Strength Policy and SSL Handshake over TLS

查看:2416
本文介绍了Java 8,JCE无限强度策略和SSL上的SSL握手的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于Java 8,只支持 TLSv1 的服务器无法从分区操作系统安全套接字连接



版本

  java版本1.8.0_45
Java环境(build 1.8.0_45-b14)
Java HotSpot™64位服务器虚拟机(构建25.45-b02,混合模式)

  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;

/ **
*创建于jigar.joshi在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(本地套接字地址=
+ 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

问题:




  • 为什么能够选择 TLSv1 在OSX上,而不是在CentOS?


  • 如何告诉JVM按特定顺序使用协议,或者如果它按版本考虑顺序,那么我如何告诉它也可以尝试 v1




>

我有无限强度的JCE策略安装JRE导致这一点,它没有这样工作,所以OSX和CentOS差异已经走了,我仍然可以使它工作吗?



编辑



输出

  Socket类:class sun.security.ssl.SSLSocketImpl 
远程地址= efm.sandbox.vovici.com/206.132.29.15
远程端口= 443
本地套接字地址= /10.10.152.143:50376
本地地址= /10.10.152.143
本地端口= 50376
需要客户端认证= false
密码套件= SSL_NULL_WITH_NULL_NULL
Protocol = NONE
javax.net.ssl.SSLException:连接已关闭:javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接
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)
在SSLTester.main(SSLTester.java:24)
引发者:javax.net.ssl.SSLHandshakeException:Remote主机在握手期间关闭连接
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)
在sun.security.ssl.SSLSocketImpl.getSession(SSLSocketImpl.java:2225)
在SSLTester.printSocketInfo(SSLTester。 java:56)
at SSLTester.main(SSLTester.java:23)
原因:java.io.EOFException:SSL对等关闭不正确
at sun.security.ssl.InputRecord。 read(InputRecord.java:505)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:961)
... 5 more
javax.net.ssl.SSLException:连接已关闭:javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接


解决方案

尝试使用以下方法将协议限制为 TLSv1

  -Djdk.tls.client.protocols = TLSv1 

有关详细信息,请参阅此页: https://docs.oracle.com /javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2



希望这有帮助,



尤里


With Java 8, server which only supports TLSv1, it fails to make secure socket connection from cent OS

Version

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)

Source

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());
    }

}

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

debug notes:

-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 

Question:

  • Why it is able to choose TLSv1 on OSX and not on CentOS?

  • 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

Edit:

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 ?

Edit:

Output

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

解决方案

Try limiting the protocols to just TLSv1 using:

-Djdk.tls.client.protocols=TLSv1

See this page for more details: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2

Hope this helps,

Yuri

这篇关于Java 8,JCE无限强度策略和SSL上的SSL握手的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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