在 HttpsURLConnection 中禁用 SSL 作为协议

Posted

技术标签:

【中文标题】在 HttpsURLConnection 中禁用 SSL 作为协议【英文标题】:Disable SSL as a protocol in HttpsURLConnection 【发布时间】:2014-12-25 08:01:28 【问题描述】:

由于POODLE 漏洞,我的托管在 Amazon AWS 中的服务器不再支持 SSLv3。

因此,我的 android 应用对服务器进行的第一次 HTTPS 连接会在建立连接时导致错误。

Error reading server response: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x77d8ab68: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x7339ad74:0x00000000)
       [....]
Caused by: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x77d8ab68: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x7339ad74:0x00000000)
       at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:448)
       at com.android.okhttp.Connection.upgradeToTls(Connection.java:146)
       at com.android.okhttp.Connection.connect(Connection.java:107)
       at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
       at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
       at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)

错误仅发生在第一个请求中。后续请求会工作一段时间。

为了解决这个问题,我尝试从 Android 客户端接受的协议列表中删除 SSL,并确保我只使用 TLS。 为此,我设置了一个自定义 SSLSocketFactory,它将 SSL 从启用的协议和支持的密码套件列表中删除。

/**
 * SSLSocketFactory that wraps one existing SSLSocketFactory and delegetes into it adding
 * a new cipher suite
 */
public class TLSOnlySocketFactory extends SSLSocketFactory 

    private final SSLSocketFactory delegate;

    public TLSOnlySocketFactory(SSLSocketFactory delegate) 
        this.delegate = delegate;
    

    @Override
    public String[] getDefaultCipherSuites() 

        return getPreferredDefaultCipherSuites(this.delegate);
    

    @Override
    public String[] getSupportedCipherSuites() 
        return getPreferredSupportedCipherSuites(this.delegate);
    



    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException 
        final Socket socket = this.delegate.createSocket(s, host, port, autoClose);

        ((SSLSocket)socket).setEnabledCipherSuites(getPreferredDefaultCipherSuites(delegate));
        ((SSLSocket)socket).setEnabledProtocols(getEnabledProtocols((SSLSocket)socket));

        return socket;
    



   [.....]

        ((SSLSocket)socket).setEnabledCipherSuites(getPreferredDefaultCipherSuites(delegate));
        ((SSLSocket) socket).setEnabledProtocols(getEnabledProtocols((SSLSocket)socket));

        return socket;
    

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException 
        final Socket socket = this.delegate.createSocket(host, port);

        ((SSLSocket)socket).setEnabledCipherSuites(getPreferredDefaultCipherSuites(delegate));
        ((SSLSocket) socket).setEnabledProtocols(getEnabledProtocols((SSLSocket)socket));

        return socket;
    

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException 
        final Socket socket = this.delegate.createSocket(address, port, localAddress, localPort);

        ((SSLSocket)socket).setEnabledCipherSuites(getPreferredDefaultCipherSuites(delegate));
        ((SSLSocket) socket).setEnabledProtocols(getEnabledProtocols((SSLSocket)socket));

        return socket;
    

    private String[] getPreferredDefaultCipherSuites(SSLSocketFactory sslSocketFactory) 
        return getCipherSuites(sslSocketFactory.getDefaultCipherSuites());
    

    private String[] getPreferredSupportedCipherSuites(SSLSocketFactory sslSocketFactory) 
        return getCipherSuites(sslSocketFactory.getSupportedCipherSuites());
    

    private String[] getCipherSuites(String[] cipherSuites) 
        final ArrayList<String> suitesList = new ArrayList<String>(Arrays.asList(cipherSuites));
        final Iterator<String> iterator = suitesList.iterator();
        while (iterator.hasNext()) 
            final String cipherSuite = iterator.next();
            if (cipherSuite.contains("SSL")) 
                iterator.remove();
            
        
        return suitesList.toArray(new String[suitesList.size()]);
    

    private String[] getEnabledProtocols(SSLSocket socket) 
        final ArrayList<String> protocolList = new ArrayList<String>(Arrays.asList(socket.getSupportedProtocols()));
        final Iterator<String> iterator = protocolList.iterator();
        while (iterator.hasNext()) 
            final String protocl = iterator.next();
            if (protocl.contains("SSL")) 
                iterator.remove();
            
        
        return protocolList.toArray(new String[protocolList.size()]);
     


如您所见,我的 SSLSocketFactory 委托给另一个 SSLSocketFactory,它所做的只是从启用的协议列表中删除 SSL。

我将这家工厂建立为

final TLSOnlySocketFactory tlsOnlySocketFactory = new TLSOnlySocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
HttpsURLConnection.setDefaultSSLSocketFactory(tlsOnlySocketFactory);

这并不能解决问题。有时,我仍然会在建立连接时看到错误。奇怪的是,这并不能解决问题,但它显然可以最大限度地减少问题的发生。

如何强制我的 Android 客户端中的 HttpsUrlConnection 仅使用 TLS?

谢谢。

【问题讨论】:

你解决了错误的问题。你不必这样做。您的问题出在其他地方。 如果这不是正确的方法,我应该如何确保我的 HttpsUrlConnection 仅使用 TLS? 嗨,我也遇到了这个问题。你找到解决这个问题的方法了吗?我也需要在全球范围内解决它,因为我使用的一些罐子也受到了影响 @EJP 你知道如何解决这个问题吗?如果是这样,请给我们一些提示:D 我没有设法修复它。我很困惑。到目前为止,我发现的解决方法是: 1. 使用 Apache Http Client 而不是 HttpURLConnection(这很糟糕)。 2.使用HttpURLConnection,当我捕捉到以SSLHandshakeException为原因的IOException时,静默重试请求(这也很糟糕)。 【参考方案1】:

我想我已经解决了这个问题。基本思想与问题中的代码相同(避免 SSLv3 作为唯一可用的协议),但执行它的代码不同:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
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.SSLParameters;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

    /**
     * @link javax.net.ssl.SSLSocketFactory that doesn't allow @code SSLv3 only connections
     * <p>fixes https://github.com/koush/ion/issues/386</p>
     *
     * <p> see https://code.google.com/p/android/issues/detail?id=78187 </p>
     */
    public class NoSSLv3Factory extends SSLSocketFactory 
        private final SSLSocketFactory delegate;

        public NoSSLv3Factory() 
            this.delegate = HttpsURLConnection.getDefaultSSLSocketFactory();
        

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

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

        private static 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));
        

        /**
         * Created by robUx4 on 25/10/2014.
         */
        private static 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 setSSLParameters(SSLParameters p) 
                delegate.setSSLParameters(p);
            

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

        /**
         * An @link javax.net.ssl.SSLSocket that doesn't allow @code SSLv3 only connections
         * <p>fixes https://github.com/koush/ion/issues/386</p>
         */
        private static class NoSSLv3SSLSocket extends DelegateSSLSocket 

            private NoSSLv3SSLSocket(SSLSocket delegate) 
                super(delegate);

                String canonicalName = delegate.getClass().getCanonicalName();
                if (!canonicalName.equals("org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl")) 
                    // try replicate the code from HttpConnection.setupSecureSocket()
                    try 
                        Method msetUseSessionTickets = delegate.getClass().getMethod("setUseSessionTickets", boolean.class);
                        if (null != msetUseSessionTickets) 
                            msetUseSessionTickets.invoke(delegate, true);
                        
                     catch (NoSuchMethodException ignored) 
                     catch (InvocationTargetException ignored) 
                     catch (IllegalAccessException ignored) 
                    
                
            

            @Override
            public void setEnabledProtocols(String[] protocols) 
                if (protocols != null && protocols.length == 1 && "SSLv3".equals(protocols[0])) 
                    // no way jose
                    // see issue https://code.google.com/p/android/issues/detail?id=78187
                    List<String> enabledProtocols = new ArrayList<String>(Arrays.asList(delegate.getEnabledProtocols()));
                    if (enabledProtocols.size() > 1) 
                        enabledProtocols.remove("SSLv3");
                    
                    protocols = enabledProtocols.toArray(new String[enabledProtocols.size()]);
                
                super.setEnabledProtocols(protocols);
            
        

    

在您的代码中的某处,在创建连接之前:

    static 
    HttpsURLConnection.setDefaultSSLSocketFactory(new NoSSLv3Factory());

此代码取自https://code.google.com/p/android/issues/detail?id=78187,您可以在其中找到关于为什么在 Android 4.X 中发生这种情况的完整解释。

我已经在生产中使用了一个星期,并且似乎成功了。

【讨论】:

嗨,这个修复对我有用,但是用固定代码运行我的应用程序一次,并且卸载并安装了旧版本 -> 现在旧版本仍然有效.... android 系统是否缓存这个在任何地方设置?我可以删除它吗?重启也没有帮助 @GaRRaPeTa 我使用了 NoSSLv3Factory 客户端,但是它无法正常工作 Samsung S3 设备。在应用程序 WebView 中加载 url 时,它给出的错误是 “找不到网页”。这是特定于设备的问题吗?如果没有,请告诉我我们是否需要更改 webview 的设置 我从来没有遇到过这个问题。更改 SSL 工厂的目标是您使用 HttpUrlConnection 连接到服务器的情况 - 工厂将创建不会使用过时 SSLLv3 协议的 HttpUrlConnection 对象。但是,我不知道这是否适用于 webview。我不知道 webview 在后台使用哪个 HTTP 客户端。 无论如何,如果您的 webview 显示“找不到网页”,我认为这与此无关,那只是 404,而不是由于密码套件不兼容而导致的握手问题引起的连接问题. 我仍然遇到SSLHandshakeException。我正在使用okHTTPRetrofit。像这样使用这个类:okClient.setSslSocketFactory(new NoSSLv3Factory());。这是否适用于 okHTTPRetrofit【参考方案2】:

除了@GaRRaPeTa 的响应,请让 makeSocketsafe 方法确定套接字是否尚未转换为 NoSSLv3SSLSocket 以防止 *** 问题:

    private static Socket makeSocketSafe(Socket socket) 
        if (socket instanceof SSLSocket && !(socket instanceof NoSSLv3SSLSocket)) 
            socket = new NoSSLv3SSLSocket((SSLSocket) socket);
        
        return socket;
    

附言。无法评论,因此它在单独的帖子中。

【讨论】:

嗨,我仍然遇到堆栈溢出错误,因为我调用了“HttpsURLConnection.setDefaultSSLSocketFactory(new NoSSLv3Factory());”多次,委托堆栈越来越长,我通过创建一个静态变量来解决这个问题: private static final SSLSocketFactory delegate = HttpsURLConnection.getDefaultSSLSocketFactory();【参考方案3】:

我最近使用 SSLContext(因为我需要访问 Trustmanager)而不是实现我自己的 NoSSLv3Factory 对此进行了测试,到目前为止我还没有遇到任何问题。

private getSSLContext()

    /* Load the keyStore that includes self-signed cert as a "trusted" entry. */
    KeyStore keyStore = ...  //optional
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); //optional
    tmf.init(keyStore); //optional

    //This is the important line, specifying the cipher to use and cipher provider
    SSLContext sslContext = SSLContext.getInstance("TLSv1","AndroidOpenSSL");
    ctx.init(null, tmf.getTrustManagers(), null); //if trustmanager not used pass null as the second parameter    
    return sslContext;

然后您可以像这样在 HttpsURLConnection 对象中使用它:

...
URL url = new URL("https://yourwebapp.com/");
HttpsURLConnection webConnection = (HttpsURLConnection)url.openConnection();
webConnection.setSSLSocketFactory(getSSLContext())
...    

这确实意味着,如果任何 SSL/TLS 漏洞被公开披露,您将必须时刻关注任何 TLS 漏洞并修改指定的密码。

您可以使用的受支持密码和提供程序列表are listed here

第一个代码块,这个场景的关键变化很小,主要取自this SO answer

【讨论】:

【参考方案4】:

我采用了@GaRRaPeTa 的answer 并将其捆绑到一个简单的方法调用中。使用 Android 的 HttpsURLConnection 时,您可以使用 NetCipher 库来获取现代 TLS 配置。 NetCipher 将 `HttpsURLConnection 实例配置为使用最受支持的 TLS 版本,删除 SSLv3 支持,并为该 TLS 版本配置最佳密码套件。首先,将其添加到您的 build.gradle

compile 'info.guardianproject.netcipher:netcipher:1.2'

或者您可以下载 netcipher-1.2.jar 并将其直接包含在您的应用中。然后代替调用:

HttpURLConnection connection = (HttpURLConnection) sourceUrl.openConnection();

这样称呼:

HttpsURLConnection connection = NetCipher.getHttpsURLConnection(sourceUrl);

【讨论】:

在 Android 4.0 模拟器上试过,收到“javax.net.ssl.SSLException: Connection closed by peer” 这确实会强制实施良好的 SSL 配置,因此如果您连接到仅支持 SSLv3 的服务器,那么您将收到异常。或者,如果该服务器仅支持弱密码,或者启用 TLSv1.2 存在问题。 唯一对我有用的解决方案。谢谢你,@Hans-ChristophSteiner 在 Android 2.2 设备上调用 conn.getOutputStream() 时获取“SSL 例程:SSL23_GET_SERVER_HELLO:sslv3 警报握手失败” 在调查中,上面的解决方案似乎只适用于 API 9 及更高版本。 Android 2.2 是 API 8 :/【参考方案5】:

上述解决方案对我不起作用,因此这是我为克服这个问题而学习和所做的。

对于 Android 5.0 之前的旧设备,默认安全提供程序具有以下属性:

    TSLv1 和 TSLv2 协议默认未启用 默认情况下不禁用 SSLv3 协议。

一个对我有用的解决方案是在启动应用程序时根据需要修补“提供程序”,因此它的协议列表中将不再包含 SSLv3。 从您的应用中修补 Android 的一种直接方法是:(考虑到您可以访问 Google Play 商店服务。)

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.");
    

查看:https://developer.android.com/training/articles/security-gms-provider.html?#patching 了解更多信息。

【讨论】:

【参考方案6】:

您还应该知道,对于默认情况下未启用的 Android 4.0 设备,您可以强制使用 TLS v1.2:

这应该在您的应用程序的第一行:

 try 
            ProviderInstaller.installIfNeeded(getApplicationContext());
            SSLContext sslContext;
            sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(null, null, null);
            sslContext.createSSLEngine();
         catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException
                | NoSuchAlgorithmException | KeyManagementException e) 
            e.printStackTrace();
        

【讨论】:

以上是关于在 HttpsURLConnection 中禁用 SSL 作为协议的主要内容,如果未能解决你的问题,请参考以下文章

Android:当密码错误时,带有 Authenticator 的 HttpsUrlConnection 将永远迭代(在 401 响应中)

为啥 HttpsURLConnection.get Server Certificates() 在 Java 6 和 Java7 中返回不同的结果?

如何在 Android 上使用 HttpsURLConnection 和 HttpResponseCache 强制缓存?

Java 1.6 HttpsURLConnection:java.net.SocketException:连接重置

使用weblogic作为容器遇到的问题---URL.openConnection获取连接返回HttpsURLConnection与SOAPHttpsURLConnection

发生 HttpsURLConnection 400 Bad Request 错误