为了进行测试,我试图将套接字工厂添加到我的okHttp客户端中,该客户端工厂在设置代理时会信任所有内容。这已经做过很多次了,但是我对可信任套接字工厂的实现似乎缺少了一些东西:
class TrustEveryoneManager implements X509TrustManager {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}
OkHttpClient client = new OkHttpClient();
final InetAddress ipAddress = InetAddress.getByName("XX.XXX.XXX.XXX"); // some IP
client.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipAddress, 8888)));
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = new TrustManager[]{new TrustEveryoneManager()};
sslContext.init(null, trustManagers, null);
client.setSslSocketFactory(sslContext.getSocketFactory);
没有任何请求从我的应用程序发送出去,也没有任何异常记录在日志中,因此它似乎在okHttp中静默失败。经过进一步调查,似乎Connection.upgradeToTls()
在强制握手时在okHttp中吞下了一个异常。我得到的例外是:javax.net.ssl.SSLException: SSL handshake terminated: ssl=0x74b522b0: SSL_ERROR_ZERO_RETURN occurred. You should never see this.
下面的代码生成一个SSLContext
,就像在创建不引发任何异常的SSLSocketFactory时的魅力一样:
protected SSLContext getTrustingSslContext() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
final SSLContextBuilder trustingSSLContextBuilder = SSLContexts.custom()
.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true; // Accepts any ssl cert whether valid or not.
}
});
return trustingSSLContextBuilder.build();
}
问题是我试图从我的应用程序中完全删除所有Apache HttpClient依赖项。用Apache HttpClient生成的基础代码SSLContext
看起来似乎很简单,但是由于我无法配置我的代码,因此我显然缺少了一些东西SSLContext
。
有人能够在不使用Apache HttpClient的情况下产生我想要的SSLContext实现吗?
java.net.SocketTimeoutException: Read timed out