使用okHttp信任所有证书
出于testing的目的,我试图添加一个套接字工厂到我的okHttp客户端,它设置代理时信任所有的东西。 这已经做了很多次,但我的信任套接字工厂的实现似乎是缺less的东西:
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);
没有请求正在发送出我的应用程序,没有任何例外情况得到logging,所以它似乎在okHttp内默默无闻。 经过进一步的调查,似乎在强制握手的时候,okHttp的Connection.upgradeToTls()
中有一个exception被吞噬了。 我给出的exception是: javax.net.ssl.SSLException: SSL handshake terminated: ssl=0x74b522b0: SSL_ERROR_ZERO_RETURN occurred. You should never see this.
javax.net.ssl.SSLException: SSL handshake terminated: ssl=0x74b522b0: SSL_ERROR_ZERO_RETURN occurred. You should never see this.
下面的代码产生一个SSLContext
,它在创buildSSLSocketFactory时不会产生任何exception:
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
的底层代码看起来很简单,但我显然错过了一些东西,因为我无法configuration我的SSLContext
来匹配它。
任何人都可以产生一个SSLContext实现,而不使用Apache HttpClient,而不是我想要的?
为了防止任何人在这里,这个工作的(唯一的)解决scheme是创buildOkHttpClient
就像这里解释的那样。
这里是代码:
private static OkHttpClient getUnsafeOkHttpClient() { try { // Create a trust manager that does not validate certificate chains final TrustManager[] trustAllCerts = new TrustManager[] { new 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 new java.security.cert.X509Certificate[]{}; } } }; // Install the all-trusting trust manager final SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); // Create an ssl socket factory with our all-trusting manager final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]); builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); OkHttpClient okHttpClient = builder.build(); return okHttpClient; } catch (Exception e) { throw new RuntimeException(e); } }
以下方法已被弃用
sslSocketFactory(SSLSocketFactory sslSocketFactory)
考虑更新它
sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager)
更新okhttp3.0,getAcceptedIssuers()函数必须返回一个空数组而不是null
SSLSocketFactory不公开其X509TrustManager,这是OkHttpbuild立一个干净的证书链所需的字段。 此方法反而必须使用reflection来提取信任pipe理器。 应用程序应该更喜欢调用sslSocketFactory(SSLSocketFactory,X509TrustManager),避免这种reflection。
OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslContext.getSocketFactory(), new 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 new java.security.cert.X509Certificate[]{}; } });
你永远不应该在代码中重写证书validation! 如果需要进行testing,请使用内部/testingCA并在设备或模拟器上安装CA根证书。 如果您不知道如何设置CA,则可以使用BurpSuite或Charles Proxy。
- ViewPager:recursion进入executePendingTransactions
- android textview填充行之间
- 我怎样才能检测到我的应用程序Androidselect哪个布局?
- android:ViewPager和HorizontalScrollVIew
- Android:UnknownHostException
- Android上支持的语言/区域设置列表是什么?
- Android:从图库加载的位图在ImageView中旋转
- Android:CollapsingToolbarLayout和SwipeRefreshLayout卡住了
- 如何将onClick事件传递给它的父母在Android上?