我面临一个奇怪的问题。我使用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攻击,但我确切知道我在做什么。 :)