2015-04-28 102 views
41

我试图运行Android中Javax.net.ssl.SSLHandshakeException:javax.net.ssl.SSLProtocolException:SSL握手中止:失败的SSL库,通常一个协议错误

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

在下面的代码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 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 
+0

做你检查你的应用程序上真实的设备? –

+0

它是什么例外?堆栈跟踪? – EJP

+0

@PareshMayani是的,即使在安装有Android 4.0的真实设备上,它也会显示异常。 –

回答

63

我为它找到解决方案,通过分析使用Wireshark的数据包。我发现的是,在建立安全连接的同时,android从TLSv1回落到SSLv3。这是Android版本< 4.4中的一个错误,可以通过从已启用协议列表中删除SSLv3协议来解决。我做了一个名为NoSSLv3SocketFactory.java的自定义socketFactory类。使用它来创建一个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); 
    } 
} 
} 

使用,而连接这个类是这样的:

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

UPDATE:

现在,正确的解决办法是使用Google Play Services安装更新的安全提供:

ProviderInstaller.installIfNeeded(getApplicationContext()); 

This effectivel y使您的应用能够访问较新版本的OpenSSL和Java安全提供程序,其中包括对SSLEngine中的TLSv1.2的支持。一旦安装了新的供应商,您可以创建支持的SSLv3,使用TLSv1,TLSv1.1和TLSv1.2工作的通常方式的SSLEngine:

SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); 
    sslContext.init(null, null, null); 
    SSLEngine engine = sslContext.createSSLEngine(); 

,也可以使用engine.setEnabledProtocols限制启用的协议。

不要忘了添加以下的依赖(latest version found here):

compile 'com.google.android.gms:play-services-auth:11.8.0' 

欲了解更多信息,结账这个link

+13

如果我在棒棒糖设备上发生此错误,该怎么办? –

+1

真的很棒...它适用于Android 4.3 –

+1

适用于Android API级别22,很好的工作! –

1

只有当我在genymotion上使用代理(< 4.4)时,它才能被重复使用。

检查 设置 - >无线&网络 - >无线网络的代理设置 - >(长按WiredSSID) - >修改网络

选择显示高级选项: 代理设置为NONE。

61

方案

我正上运行Android的版本比Android 5.0的早期设备SSLHandshake例外。在我的使用案例中,我也想创建一个TrustManager来信任我的客户端证书。

我实现了NoSSLv3SocketFactoryNoSSLv3Factory从我的客户端支持的协议列表中删除SSLv3,但我没有得到任何这些解决方案的工作。

有些事情我了解到:

  • 在设备上年龄比的是Android 5.0 TLSv1.1和TLSv1.2工作协议不是默认启用的。
  • 默认情况下,SSLv3协议在Android 5.0之前的设备上未被禁用。
  • SSLv3 is not a secure协议,因此需要在建立连接之前将其从客户端支持的协议列表中删除。

什么工作对我来说

允许Android的安全Provider来开始你的应用程序时更新。

5.0+之前的默认提供程序不会禁用SSLv3。如果您可以访问Google Play服务,则从您的应用修补Android的安全提供程序相对比较简单。

private void updateAndroidSecurityProvider(Activity callingActivity) { 
    try { 
     ProviderInstaller.installIfNeeded(this); 
    } catch (GooglePlayServicesRepairableException e) { 
     // Thrown when Google Play Services is not installed, up-to-date, or enabled 
     // Show dialog to allow users to install, update, or otherwise enable Google Play services. 
     GooglePlayServicesUtil.getErrorDialog(e.getConnectionStatusCode(), callingActivity, 0); 
    } catch (GooglePlayServicesNotAvailableException e) { 
     Log.e("SecurityException", "Google Play Services not available."); 
    } 
} 

如果你现在创建OkHttpClient或HttpURLConnection的TLSv1.1和TLSv1.2工作应该作为协议和SSLv3的应该被删除。如果在调用ProviderInstaller.installIfNeeded(...)之前初始化客户端/连接(或者更具体地说它是SSLContext),那么它将需要被重新创建。

不要忘了添加以下的依赖(latest version found here):

compile 'com.google.android.gms:play-services-auth:11.8.0' 

来源:

除了

我并不需要明确设置其密码算法我的客户应该使用,但我发现了一个SO发布推荐那些被认为是最安全的,在写作的时候: NoSSLv3SocketFactory:Which Cipher Suites to enable for SSL Socket?

+1

感谢队友,你刚刚帮助了一位朋友! :) – ticofab

+0

这需要更多upvotes。谢谢一堆 – tmho

+0

在我的情况下工作 –

0

我这个解决的问题。 java的

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); 
      super.setEnabledProtocols(new String[]{"TLSv1.2"}); 
     } 
    } 

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

主要类:

URL url = new URL("https://www.example.com/test.png"); 
URLConnection l_connection = null; 
SSLContext sslcontext = SSLContext.getInstance("TLSv1.2"); 
sslcontext.init(null, null, null); 
SSLSocketFactory NoSSLv3Factory = new NoSSLv3SocketFactory(sslcontext.getSocketFactory()); 
0

这解决了这个问题对我来说:

The Android documentation for SSLSocket says that TLS 1.1 and TLS 1.2 is supported within android starting API level 16+ (Android 4.1, Jelly Bean). But it is by default disabled but starting with API level 20+ (Android 4.4 for watch, Kitkat Watch and Android 5.0 for phone, Lollipop) they are enabled. But it is very hard to find any documentation about how to enable it for phones running 4.1 for example. To enable TLS 1.1 and 1.2 you need to create a custom SSLSocketFactory that is going to proxy all calls to a default SSLSocketFactory implementation. In addition to that do we have to override all createSocket methods and callsetEnabledProtocols on the returned SSLSocket to enable TLS 1.1 and TLS 1.2. For an example implementation just follow the link below.

android 4.1. enable tls1.1 and tls 1.2