出于测试的目的,我尝试在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中静默失败。经过进一步调查,似乎在强制握手时,okHttp的Connection.upgradeToTls()
中包含了一个异常。我得到的异常是: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实现来完成我所希望的任务吗?
8条答案
按热度按时间nzkunb0c1#
以防万一有人在这里福尔斯,(唯一)对我有效的解决方案是像解释here那样创建
OkHttpClient
。下面是代码:
qmelpv7a2#
我为Kotlin做了一个扩展函数。把它粘贴到你喜欢的任何地方,然后在创建
OkHttpClient
的时候导入它。像这样使用它:
vxbzzdmp3#
这是sonxurxo在Kotlin的解决方案,如果有人需要的话。
a5g8bdjr4#
更新OkHttp 3.0,
getAcceptedIssuers()
函数必须返回空数组,而不是null
。jtw3ybtb5#
以下方法已弃用
考虑将其更新为
q3qa4bjr6#
SSLSocketFactory不公开它的X509TrustManager,这是OkHttp构建干净的证书链所需的字段。此方法必须使用反射来提取信任管理器。应用程序应首选调用sslSocketFactory(SSLSocketFactory,X509TrustManager),这样可以避免此类反射。
来源:OkHttp文档
ruyhziif7#
如果有人需要Scala解决方案,这就是它
}
5anewei68#
你不应该试图在代码中覆盖证书验证!如果你需要测试,使用内部/测试CA并在设备或模拟器上安装CA根证书。如果你不知道如何设置CA,你可以使用BurpSuite或Charles Proxy。