Javax.net.ssl​​.SSLHandshakeException:javax.net.ssl​​.SSLProtocolException:SSL握手终止:失败的SSL库,通常一个协议错误 [英] Javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: Failure in SSL library, usually a protocol error

查看:284
本文介绍了Javax.net.ssl​​.SSLHandshakeException:javax.net.ssl​​.SSLProtocolException:SSL握手终止:失败的SSL库,通常一个协议错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图运行下面的code在机器人

 的URLConnection l_connection = NULL;
        //创建连接
        uzip =新UnZipData(mContext);
        l_url =新的URL(SERVERURL);

        如果(https开头.equals(l_url.getProtocol())){
            的System.out.println(&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;>;>> TLS&GT之前>>>&GT ;>>>>中);
            的SSLContext = SSLContext.getInstance(TLS);
            的System.out.println(&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&所述;之后的TLS>>>>>>>&GT ;>>>>中);
            sslcontext.init(空,
                    新的TrustManager [] {新CustomTrustManager()},
                    新java.security.SecureRandom中());
            HttpsURLConnection
                    .setDefaultHostnameVerifier(新CustomHostnameVerifier());
            HttpsURLConnection.setDefaultSSLSocketFactory(的SSLContext
                    .getSocketFactory());

            l_connection =(HttpsURLConnection)l_url.openConnection();
            ((HttpsURLConnection)l_connection).setRequestMethod(POST);
        } 其他 {
            l_connection =(HttpURLConnection类)l_url.openConnection();
            ((HttpURLConnection类)l_connection).setRequestMethod(POST);
        }
        /*System.setProperty("http.agent,Android_Phone); * /


        l_connection.setConnectTimeout(10000);
        l_connection.setRequestProperty(内容语言,EN-US);
        l_connection.setUseCaches(假);
        l_connection.setDoInput(真正的);
        l_connection.setDoOutput(真正的);
        的System.out.println(&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;&其中;连接&GT之前;>>>>>>&GT ;>>>>中);
        l_connection.connect();
 

l_connection.connect(),它给这个SSLhandshakeException。有时候它的工作原理,但大多数时间它给人的例外。它只是发生在Android 4.0模拟器。我测试了它在Android 4.4和5.0,它工作正常。有什么能这样做的原因是什么?请帮忙

堆栈跟踪

  04-28 15:51:13.143:W / System.err的(2915):javax.net.ssl​​.SSLHandshakeException:javax.net.ssl​​.SSLProtocolException:SSL握手中止: SSL = 0x870c918:失败的SSL库,通常一个协议错误
04-28 15:51:13.143:W / System.err的(2915):错误:14077410:SSL例程:SSL23_GET_SERVER_HELLO:SSLv3的警报握手失败(外部/ OpenSSL的/ SSL / s23_clnt.c:658 0xb7c393a1:00000000)
04-28 15:51:13.143:W / System.err的(2915):在org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:460)
04-28 15:51:13.143:W / System.err的(2915):在org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)
04-28 15:51:13.143:W / System.err的(2915):在libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
04-28 15:51:13.143:W / System.err的(2915):在libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
04-28 15:51:13.153:W / System.err的(2915):在libcore.net.http.HttpsURLConnectionImpl $ HttpsEngine.connect(HttpsURLConnectionImpl.java:441)
04-28 15:51:13.153:W / System.err的(2915):在libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
04-28 15:51:13.153:W / System.err的(2915):在libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
04-28 15:51:13.153:W / System.err的(2915):在libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
04-28 15:51:13.153:W / System.err的(2915):在libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
04-28 15:51:13.153:W / System.err的(2915):在com.ofss.fcdb.mobile.android.rms.helpers.NetworkConnector.getConnection(NetworkConnector.java:170)
04-28 15:51:13.153:W / System.err的(2915):在com.ofss.fcdb.mobile.android.rms.util.InitiateRMS $ 2.运行(InitiateRMS.java:221)
04-28 15:51:13.153:W / System.err的(2915):在java.lang.Thread.run(Thread.java:856)
04-28 15:51:13.153:W / System.err的(2915):javax.net.ssl​​.SSLProtocolException:产生的原因SSL握手中止:SSL = 0x870c918:失败的SSL库,通常一个协议错误
04-28 15:51:13.153:W / System.err的(2915):错误:14077410:SSL例程:SSL23_GET_SERVER_HELLO:SSLv3的警报握手失败(外部/ OpenSSL的/ SSL / s23_clnt.c:658 0xb7c393a1:00000000)
04-28 15:51:13.153:W / System.err的(2915):在org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(本机方法)
04-28 15:51:13.153:W / System.err的(2915):在org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
04-28 15:51:13.153:W / System.err的(2915):11 ...更多
04-28 16:42:44.139:W /的ResourceType(3140):没有包装标识的资源数量00000000获得价值时,
 

解决方案

我为它找到了解决方案,通过分析使用Wireshark的数据包。我发现的是,同时使安全连接,机器人是回落至的SSLv3 的TLSv1 。这是Android的版本℃的错误; 4.4,并且它可以通过从启用的协议列表的SSLv3的协议解决。我做了一个叫NoSSLv3SocketFactory.java定制的SocketFactory类。使用此做出的SocketFactory。

  / *版权所有2015年Bhavit辛格Sengar
Apache许可证下授权,版本2.0(以下简称许可证);
你可能不使用这个文件除了在合规与License.You可在获得许可证的副本

http://www.apache.org/licenses/LICENSE-2.0
除非适用法律要求或书面同意,软件
该许可证下发布分布在原样的基础上,
无担保或任何形式的条件,无论是EX preSS或暗示的保证。
查看许可证的特定语言的管理权限和
该许可证下的限制。* /

进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.io.OutputStream中;
进口的java.net.InetAddress;
进口的java.net.Socket;
进口java.net.SocketAddress;
进口java.net.SocketException异常;
进口java.nio.channels.SocketChannel中;
进口的java.util.ArrayList;
进口java.util.Arrays中;
进口的java.util.List;
进口javax.net.ssl​​.HandshakeCompletedListener;
进口javax.net.ssl​​.HttpsURLConnection中;
进口javax.net.ssl​​.SSLSession中;
进口javax.net.ssl​​.SSLSocket中;
进口javax.net.ssl​​.SSLSocketFactory;


公共类NoSSLv3SocketFactory扩展的SSLSocketFactory {
    私人最终SSLSocketFactory的代表;

公共NoSSLv3SocketFactory(){
    this.delegate = HttpsURLConnection.getDefaultSSLSocketFactory();
}

公共NoSSLv3SocketFactory(SSLSocketFactory的代表){
    this.delegate =委托;
}

@覆盖
公众的String [] getDefaultCipherSuites(){
    返回delegate.getDefaultCipherSuites();
}

@覆盖
公众的String [] getSupportedCipherSuites(){
    返回delegate.getSupportedCipherSuites();
}

专用插座makeSocketSafe(Socket套接字){
    如果(插座的instanceof SSLSocket){
        插座=新NoSSLv3SSLSocket((SSLSocket)插座);
    }
    返回插座;
}

@覆盖
公共插座中的createSocket(插座S,字符串主机,INT端口,布尔自动关闭)抛出IOException异常{
    返回makeSocketSafe(delegate.createSocket(S,主机,端口自动关闭));
}

@覆盖
公共插座中的createSocket(字符串主机,INT端口)抛出IOException异常{
    返回makeSocketSafe(delegate.createSocket(主机,端口));
}

@覆盖
公共插座中的createSocket(字符串主机,INT端口,本地主机的InetAddress,INT将localPort)抛出IOException异常{
    返回makeSocketSafe(delegate.createSocket(主机,端口,本地主机,将localPort));
}

@覆盖
公共插座中的createSocket(InetAddress类主机,INT端口)抛出IOException异常{
    返回makeSocketSafe(delegate.createSocket(主机,端口));
}

@覆盖
公共插座中的createSocket(InetAddress类地址,INT端口,InetAddress类将localAddress,INT将localPort)抛出IOException异常{
    返回makeSocketSafe(delegate.createSocket(地址,端口,将localAddress,将localPort));
}

私有类NoSSLv3SSLSocket扩展DelegateSSLSocket {

    私人NoSSLv3SSLSocket(SSLSocket代表){
        超(代表);

    }

    @覆盖
    公共无效setEnabledProtocols(字符串[]协议){
        如果(协议=空&安培;!&安培; protocols.length == 1&安培;&安培;的SSLv3.equals(协议[0])){

            名单<字符串> enabledProtocols =新的ArrayList<字符串>(Arrays.asList(delegate.getEnabledProtocols()));
            如果(enabledProtocols.size()→1){
                enabledProtocols.remove(SSLv3的);
                的System.out.println(从启用的协议中删除的SSLv3);
            } 其他 {
                的System.out.println(SSL坚持供协议+将String.valueOf(enabledProtocols));
            }
            协议= enabledProtocols.toArray(新的String [enabledProtocols.size());
        }

        super.setEnabledProtocols(协议);
    }
}

公共类DelegateSSLSocket扩展SSLSocket {

    受保护的最终SSLSocket代表;

    DelegateSSLSocket(SSLSocket代表){
        this.delegate =委托;
    }

    @覆盖
    公众的String [] getSupportedCipherSuites(){
        返回delegate.getSupportedCipherSuites();
    }

    @覆盖
    公众的String [] getEnabledCipherSuites(){
        返回delegate.getEnabledCipherSuites();
    }

    @覆盖
    公共无效setEnabledCipherSuites(字符串[]套房){
        delegate.setEnabledCipherSuites(套);
    }

    @覆盖
    公众的String [] getSupportedProtocols(){
        返回delegate.getSupportedProtocols();
    }

    @覆盖
    公众的String [] getEnabledProtocols(){
        返回delegate.getEnabledProtocols();
    }

    @覆盖
    公共无效setEnabledProtocols(字符串[]协议){
        delegate.setEnabledProtocols(协议);
    }

    @覆盖
    公众的SSLSession的getSession(){
        返回delegate.getSession();
    }

    @覆盖
    公共无效addHandshakeCompletedListener(HandshakeCompletedListener监听器){
        delegate.addHandshakeCompletedListener(听众);
    }

    @覆盖
    公共无效removeHandshakeCompletedListener(HandshakeCompletedListener监听器){
        delegate.removeHandshakeCompletedListener(听众);
    }

    @覆盖
    公共无效startHandshake()抛出IOException异常{
        delegate.startHandshake();
    }

    @覆盖
    公共无效setUseClientMode(布尔模式){
        delegate.setUseClientMode(模式);
    }

    @覆盖
    公共布尔getUseClientMode(){
        返回delegate.getUseClientMode();
    }

    @覆盖
    公共无效setNeedClientAuth(布尔需要){
        delegate.setNeedClientAuth(需要);
    }

    @覆盖
    公共无效setWantClientAuth(布尔想要的){
        delegate.setWantClientAuth(希望);
    }

    @覆盖
    公共布尔getNeedClientAuth(){
        返回delegate.getNeedClientAuth();
    }

    @覆盖
    公共布尔getWantClientAuth(){
        返回delegate.getWantClientAuth();
    }

    @覆盖
    公共无效setEnableSessionCreation(布尔标志){
        delegate.setEnableSessionCreation(标志);
    }

    @覆盖
    公共布尔getEnableSessionCreation(){
        返回delegate.getEnableSessionCreation();
    }

    @覆盖
    公共无效的bind(SocketAddress的localAddr)抛出IOException异常{
        delegate.bind(localAddr);
    }

    @覆盖
    市民同步无效关闭()抛出IOException异常{
        delegate.close();
    }

    @覆盖
    公共无效连接(SocketAddress的remoteAddr)抛出IOException异常{
        delegate.connect(remoteAddr);
    }

    @覆盖
    公共无效连接(SocketAddress的remoteAddr,INT超时)抛出IOException异常{
        delegate.connect(remoteAddr,超时);
    }

    @覆盖
    公众的SocketChannel getChannel(){
        返回delegate.getChannel();
    }

    @覆盖
    公众的InetAddress getInetAddress(){
        返回delegate.getInetAddress();
    }

    @覆盖
    公众的InputStream的getInputStream()抛出IOException异常{
        返回delegate.getInputStream();
    }

    @覆盖
    公共布尔getKeepAlive()抛出SocketException {
        返回delegate.getKeepAlive();
    }

    @覆盖
    公众的InetAddress getLocalAddress(){
        返回delegate.getLocalAddress();
    }

    @覆盖
    公众诠释的getLocalPort(){
        返回delegate.getLocalPort();
    }

    @覆盖
    公共SocketAddress的getLocalSocketAddress(){
        返回delegate.getLocalSocketAddress();
    }

    @覆盖
    公共布尔getOOBInline()抛出SocketException {
        返回delegate.getOOBInline();
    }

    @覆盖
    公众的OutputStream的getOutputStream()抛出IOException异常{
        返回delegate.getOutputStream();
    }

    @覆盖
    公众诠释的getPort(){
        返回delegate.getPort();
    }

    @覆盖
    公共同步INT getReceiveBufferSize()抛出SocketException {
        返回delegate.getReceiveBufferSize();
    }

    @覆盖
    公共SocketAddress的getRemoteSocketAddress(){
        返回delegate.getRemoteSocketAddress();
    }

    @覆盖
    公共布尔getReuseAddress()抛出SocketException {
        返回delegate.getReuseAddress();
    }

    @覆盖
    公共同步INT getSendBufferSize()抛出SocketException {
        返回delegate.getSendBufferSize();
    }

    @覆盖
    公众诠释getSoLinger()抛出SocketException {
        返回delegate.getSoLinger();
    }

    @覆盖
    公共同步INT getSoTimeout()抛出SocketException {
        返回delegate.getSoTimeout();
    }

    @覆盖
    公共布尔getTcpNoDelay()抛出SocketException {
        返回delegate.getTcpNoDelay();
    }

    @覆盖
    公众诠释getTrafficClass()抛出SocketException {
        返回delegate.getTrafficClass();
    }

    @覆盖
    公共布尔一个isBound(){
        返回delegate.isBound();
    }

    @覆盖
    公共布尔在isClosed(){
        返回delegate.isClosed();
    }

    @覆盖
    公共布尔isConnected(){
        返回delegate.isConnected();
    }

    @覆盖
    公共布尔isInputShutdown(){
        返回delegate.isInputShutdown();
    }

    @覆盖
    公共布尔isOutputShutdown(){
        返回delegate.isOutputShutdown();
    }

    @覆盖
    公共无效sendUrgentData(int值)抛出IOException异常{
        delegate.sendUrgentData(值);
    }

    @覆盖
    公共无效setKeepAlive(布尔的keepalive)抛出SocketException {
        delegate.setKeepAlive(持续);
    }

    @覆盖
    公共无效setOOBInline(布尔OOBINLINE)抛出SocketException {
        delegate.setOOBInline(OOBINLINE);
    }

    @覆盖
    公共无效setPerformance preferences(INT connectionTime,诠释延迟,INT带宽){
        delegate.setPerformance preferences(connectionTime,时延,带宽);
    }

    @覆盖
    市民同步无效setReceiveBufferSize(INT尺寸)抛出SocketException {
        delegate.setReceiveBufferSize(大小);
    }

    @覆盖
    公共无效setReuseAddress(布尔复用)抛出SocketException {
        delegate.setReuseAddress(再利用);
    }

    @覆盖
    市民同步无效setSendBufferSize(INT尺寸)抛出SocketException {
        delegate.setSendBufferSize(大小);
    }

    @覆盖
    公共无效setSoLinger(布尔上,INT超时)抛出SocketException {
        delegate.setSoLinger(上超时);
    }

    @覆盖
    市民同步无效setSoTimeout(INT超时)抛出SocketException {
        delegate.setSoTimeout(超时);
    }

    @覆盖
    公共无效setTcpNoDelay(布尔上)抛出SocketException {
        delegate.setTcpNoDelay(上);
    }

    @覆盖
    公共无效setTrafficClass(int值)抛出SocketException {
        delegate.setTrafficClass(值);
    }

    @覆盖
    公共无效shutdownInput()抛出IOException异常{
        delegate.shutdownInput();
    }

    @覆盖
    公共无效shutdownOutput()抛出IOException异常{
        delegate.shutdownOutput();
    }

    @覆盖
    公共字符串的toString(){
        返回delegate.toString();
    }

    @覆盖
    公共布尔等于(对象o){
        返回delegate.equals(O);
    }
}
}
 

使用这个类像这样在连接:

 的SSL连接的SSL连接= SSLContext.getInstance(使用TLSv1);

            sslcontext.init(空,
                    空值,
                    空值);
            SSLSocketFactory的NoSSLv3Factory =新NoSSLv3SocketFactory(sslcontext.getSocketFactory());

            HttpsURLConnection.setDefaultSSLSocketFactory(NoSSLv3Factory);
            l_connection =(HttpsURLConnection)l_url.openConnection();
            l_connection.connect();
 

I am trying to run the following code in android

URLConnection l_connection = null;
        // Create connection
        uzip=new UnZipData(mContext);
        l_url = new URL(serverurl);

        if ("https".equals(l_url.getProtocol())) {
            System.out.println("<<<<<<<<<<<<< Before TLS >>>>>>>>>>>>");
            sslcontext = SSLContext.getInstance("TLS");
            System.out.println("<<<<<<<<<<<<< After TLS >>>>>>>>>>>>");
            sslcontext.init(null,
                    new TrustManager[] { new CustomTrustManager()},
                    new java.security.SecureRandom());
            HttpsURLConnection
                    .setDefaultHostnameVerifier(new CustomHostnameVerifier());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext
                    .getSocketFactory());

            l_connection = (HttpsURLConnection) l_url.openConnection();
            ((HttpsURLConnection) l_connection).setRequestMethod("POST");
        } else {
            l_connection = (HttpURLConnection) l_url.openConnection();
            ((HttpURLConnection) l_connection).setRequestMethod("POST");
        }
        /*System.setProperty("http.agent", "Android_Phone");*/


        l_connection.setConnectTimeout(10000);
        l_connection.setRequestProperty("Content-Language", "en-US");
        l_connection.setUseCaches(false);
        l_connection.setDoInput(true);
        l_connection.setDoOutput(true);
        System.out.println("<<<<<<<<<<<<< Before Connection >>>>>>>>>>>>");
        l_connection.connect();

On l_connection.connect() , it is giving this SSLhandshakeException. Sometimes it works, but most of the time it gives the exception. It is only happening on Android 4.0 emulator. I tested it on Android 4.4 and 5.0, it works fine. What could be the cause of this ? Please help

STACKTRACE

    04-28 15:51:13.143: W/System.err(2915): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.143: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.143: W/System.err(2915):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:460)
04-28 15:51:13.143: W/System.err(2915):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)
04-28 15:51:13.143: W/System.err(2915):     at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
04-28 15:51:13.143: W/System.err(2915):     at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
04-28 15:51:13.153: W/System.err(2915):     at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:441)
04-28 15:51:13.153: W/System.err(2915):     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
04-28 15:51:13.153: W/System.err(2915):     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
04-28 15:51:13.153: W/System.err(2915):     at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
04-28 15:51:13.153: W/System.err(2915):     at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
04-28 15:51:13.153: W/System.err(2915):     at com.ofss.fcdb.mobile.android.rms.helpers.NetworkConnector.getConnection(NetworkConnector.java:170)
04-28 15:51:13.153: W/System.err(2915):     at com.ofss.fcdb.mobile.android.rms.util.InitiateRMS$2.run(InitiateRMS.java:221)
04-28 15:51:13.153: W/System.err(2915):     at java.lang.Thread.run(Thread.java:856)
04-28 15:51:13.153: W/System.err(2915): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.153: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.153: W/System.err(2915):     at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
04-28 15:51:13.153: W/System.err(2915):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
04-28 15:51:13.153: W/System.err(2915):     ... 11 more
04-28 16:42:44.139: W/ResourceType(3140): No package identifier when getting value for resource number 0x00000000

解决方案

I found the solution for it by analyzing the data packets using wireshark. What I found is that while making a secure connection, android was falling back to SSLv3 from TLSv1 . It is a bug in android versions < 4.4 , and it can be solved by removing the SSLv3 protocol from Enabled Protocols list. I made a custom socketFactory class called NoSSLv3SocketFactory.java. Use this to make a socketfactory.

/*Copyright 2015 Bhavit Singh Sengar
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;


public class NoSSLv3SocketFactory extends SSLSocketFactory{
    private final SSLSocketFactory delegate;

public NoSSLv3SocketFactory() {
    this.delegate = HttpsURLConnection.getDefaultSSLSocketFactory();
}

public NoSSLv3SocketFactory(SSLSocketFactory delegate) {
    this.delegate = delegate;
}

@Override
public String[] getDefaultCipherSuites() {
    return delegate.getDefaultCipherSuites();
}

@Override
public String[] getSupportedCipherSuites() {
    return delegate.getSupportedCipherSuites();
}

private Socket makeSocketSafe(Socket socket) {
    if (socket instanceof SSLSocket) {
        socket = new NoSSLv3SSLSocket((SSLSocket) socket);
    }
    return socket;
}

@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
    return makeSocketSafe(delegate.createSocket(s, host, port, autoClose));
}

@Override
public Socket createSocket(String host, int port) throws IOException {
    return makeSocketSafe(delegate.createSocket(host, port));
}

@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
    return makeSocketSafe(delegate.createSocket(host, port, localHost, localPort));
}

@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
    return makeSocketSafe(delegate.createSocket(host, port));
}

@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
    return makeSocketSafe(delegate.createSocket(address, port, localAddress, localPort));
}

private class NoSSLv3SSLSocket extends DelegateSSLSocket {

    private NoSSLv3SSLSocket(SSLSocket delegate) {
        super(delegate);

    }

    @Override
    public void setEnabledProtocols(String[] protocols) {
        if (protocols != null && protocols.length == 1 && "SSLv3".equals(protocols[0])) {

            List<String> enabledProtocols = new ArrayList<String>(Arrays.asList(delegate.getEnabledProtocols()));
            if (enabledProtocols.size() > 1) {
                enabledProtocols.remove("SSLv3");
                System.out.println("Removed SSLv3 from enabled protocols");
            } else {
                System.out.println("SSL stuck with protocol available for " + String.valueOf(enabledProtocols));
            }
            protocols = enabledProtocols.toArray(new String[enabledProtocols.size()]);
        }

        super.setEnabledProtocols(protocols);
    }
}

public class DelegateSSLSocket extends SSLSocket {

    protected final SSLSocket delegate;

    DelegateSSLSocket(SSLSocket delegate) {
        this.delegate = delegate;
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return delegate.getSupportedCipherSuites();
    }

    @Override
    public String[] getEnabledCipherSuites() {
        return delegate.getEnabledCipherSuites();
    }

    @Override
    public void setEnabledCipherSuites(String[] suites) {
        delegate.setEnabledCipherSuites(suites);
    }

    @Override
    public String[] getSupportedProtocols() {
        return delegate.getSupportedProtocols();
    }

    @Override
    public String[] getEnabledProtocols() {
        return delegate.getEnabledProtocols();
    }

    @Override
    public void setEnabledProtocols(String[] protocols) {
        delegate.setEnabledProtocols(protocols);
    }

    @Override
    public SSLSession getSession() {
        return delegate.getSession();
    }

    @Override
    public void addHandshakeCompletedListener(HandshakeCompletedListener listener) {
        delegate.addHandshakeCompletedListener(listener);
    }

    @Override
    public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) {
        delegate.removeHandshakeCompletedListener(listener);
    }

    @Override
    public void startHandshake() throws IOException {
        delegate.startHandshake();
    }

    @Override
    public void setUseClientMode(boolean mode) {
        delegate.setUseClientMode(mode);
    }

    @Override
    public boolean getUseClientMode() {
        return delegate.getUseClientMode();
    }

    @Override
    public void setNeedClientAuth(boolean need) {
        delegate.setNeedClientAuth(need);
    }

    @Override
    public void setWantClientAuth(boolean want) {
        delegate.setWantClientAuth(want);
    }

    @Override
    public boolean getNeedClientAuth() {
        return delegate.getNeedClientAuth();
    }

    @Override
    public boolean getWantClientAuth() {
        return delegate.getWantClientAuth();
    }

    @Override
    public void setEnableSessionCreation(boolean flag) {
        delegate.setEnableSessionCreation(flag);
    }

    @Override
    public boolean getEnableSessionCreation() {
        return delegate.getEnableSessionCreation();
    }

    @Override
    public void bind(SocketAddress localAddr) throws IOException {
        delegate.bind(localAddr);
    }

    @Override
    public synchronized void close() throws IOException {
        delegate.close();
    }

    @Override
    public void connect(SocketAddress remoteAddr) throws IOException {
        delegate.connect(remoteAddr);
    }

    @Override
    public void connect(SocketAddress remoteAddr, int timeout) throws IOException {
        delegate.connect(remoteAddr, timeout);
    }

    @Override
    public SocketChannel getChannel() {
        return delegate.getChannel();
    }

    @Override
    public InetAddress getInetAddress() {
        return delegate.getInetAddress();
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return delegate.getInputStream();
    }

    @Override
    public boolean getKeepAlive() throws SocketException {
        return delegate.getKeepAlive();
    }

    @Override
    public InetAddress getLocalAddress() {
        return delegate.getLocalAddress();
    }

    @Override
    public int getLocalPort() {
        return delegate.getLocalPort();
    }

    @Override
    public SocketAddress getLocalSocketAddress() {
        return delegate.getLocalSocketAddress();
    }

    @Override
    public boolean getOOBInline() throws SocketException {
        return delegate.getOOBInline();
    }

    @Override
    public OutputStream getOutputStream() throws IOException {
        return delegate.getOutputStream();
    }

    @Override
    public int getPort() {
        return delegate.getPort();
    }

    @Override
    public synchronized int getReceiveBufferSize() throws SocketException {
        return delegate.getReceiveBufferSize();
    }

    @Override
    public SocketAddress getRemoteSocketAddress() {
        return delegate.getRemoteSocketAddress();
    }

    @Override
    public boolean getReuseAddress() throws SocketException {
        return delegate.getReuseAddress();
    }

    @Override
    public synchronized int getSendBufferSize() throws SocketException {
        return delegate.getSendBufferSize();
    }

    @Override
    public int getSoLinger() throws SocketException {
        return delegate.getSoLinger();
    }

    @Override
    public synchronized int getSoTimeout() throws SocketException {
        return delegate.getSoTimeout();
    }

    @Override
    public boolean getTcpNoDelay() throws SocketException {
        return delegate.getTcpNoDelay();
    }

    @Override
    public int getTrafficClass() throws SocketException {
        return delegate.getTrafficClass();
    }

    @Override
    public boolean isBound() {
        return delegate.isBound();
    }

    @Override
    public boolean isClosed() {
        return delegate.isClosed();
    }

    @Override
    public boolean isConnected() {
        return delegate.isConnected();
    }

    @Override
    public boolean isInputShutdown() {
        return delegate.isInputShutdown();
    }

    @Override
    public boolean isOutputShutdown() {
        return delegate.isOutputShutdown();
    }

    @Override
    public void sendUrgentData(int value) throws IOException {
        delegate.sendUrgentData(value);
    }

    @Override
    public void setKeepAlive(boolean keepAlive) throws SocketException {
        delegate.setKeepAlive(keepAlive);
    }

    @Override
    public void setOOBInline(boolean oobinline) throws SocketException {
        delegate.setOOBInline(oobinline);
    }

    @Override
    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
        delegate.setPerformancePreferences(connectionTime, latency, bandwidth);
    }

    @Override
    public synchronized void setReceiveBufferSize(int size) throws SocketException {
        delegate.setReceiveBufferSize(size);
    }

    @Override
    public void setReuseAddress(boolean reuse) throws SocketException {
        delegate.setReuseAddress(reuse);
    }

    @Override
    public synchronized void setSendBufferSize(int size) throws SocketException {
        delegate.setSendBufferSize(size);
    }

    @Override
    public void setSoLinger(boolean on, int timeout) throws SocketException {
        delegate.setSoLinger(on, timeout);
    }

    @Override
    public synchronized void setSoTimeout(int timeout) throws SocketException {
        delegate.setSoTimeout(timeout);
    }

    @Override
    public void setTcpNoDelay(boolean on) throws SocketException {
        delegate.setTcpNoDelay(on);
    }

    @Override
    public void setTrafficClass(int value) throws SocketException {
        delegate.setTrafficClass(value);
    }

    @Override
    public void shutdownInput() throws IOException {
        delegate.shutdownInput();
    }

    @Override
    public void shutdownOutput() throws IOException {
        delegate.shutdownOutput();
    }

    @Override
    public String toString() {
        return delegate.toString();
    }

    @Override
    public boolean equals(Object o) {
        return delegate.equals(o);
    }
}
}

Use this class like this while connecting :

SSLContext sslcontext = SSLContext.getInstance("TLSv1");

            sslcontext.init(null,
                    null,
                    null);
            SSLSocketFactory NoSSLv3Factory = new NoSSLv3SocketFactory(sslcontext.getSocketFactory());

            HttpsURLConnection.setDefaultSSLSocketFactory(NoSSLv3Factory);
            l_connection = (HttpsURLConnection) l_url.openConnection();
            l_connection.connect();

这篇关于Javax.net.ssl​​.SSLHandshakeException:javax.net.ssl​​.SSLProtocolException:SSL握手终止:失败的SSL库,通常一个协议错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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