在Android中使用OkHTTP打开URL SSLException< 5.0但在WebView中打开很好

时间:2017-01-06 11:06:57

标签: android webview okhttp android-networking okhttp3

我面临一个奇怪的问题。我使用OkHTTP请求Web表单,解析它并将其显示为本机Android UI。

过去一切都很好但最近,Lollipop下的Android版本的请求开始失败。它开始引发以下异常:

Caused by: javax.net.ssl.SSLException: Connection closed by peer
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:405)
        at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:242)
        at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:200)
        at okhttp3.internal.connection.RealConnection.buildConnection(RealConnection.java:174)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:114)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:196)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:132)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:101)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
        at okhttp3.RealCall.execute(RealCall.java:63)

我搜索了互联网并发现它可能是因为Android在Lollipop之前禁用了TLS1.2并且服务器可能已停止支持其他协议。

但我怀疑这是问题,因为相同的URL在Lollipop以下版本的WebView中加载完全正常。这让我相信它可能是OkHTTP客户端的配置问题。

这个错误可能是什么原因?

以下是我构建HTTP客户端的方法:

public static synchronized OkHttpClient getAllAcceptingOkHttpClient() {
        if (sOkHttpClient == null) {
            SSLSocketFactory factory = getAllAcceptingSSLSocketFactory();
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.cookieJar(new JavaNetCookieJar(AadharApplication.cookieManager));
            if (factory != null) {
                builder.sslSocketFactory(factory);
            }
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            sOkHttpClient = builder.build();
        }
        return sOkHttpClient;
    }


private static SSLSocketFactory getAllAcceptingSSLSocketFactory() {
        try {
            final SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, sTrustAllCerts, new java.security.SecureRandom());
            return sslContext.getSocketFactory();
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            Log.d(TAG, "", e);
            return null;
        }
    }

    private static final TrustManager[] sTrustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[]{};
                }
            }
    };
PS:我知道这会导致MITM攻击,但我确切知道我在做什么。 :)

0 个答案:

没有答案