Trust all okHttp certificates

For testing purposes, I am trying to add a factory socket to my okHttp client, which trusts everyone while the proxy server is installed. This has been done many times, but my implementation of a trusted factory socket seems to be missing something:

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); 

No requests are sent from my application, and no exceptions are logged, so it seems that it does not work in okHttp mode. Upon further investigation, it seems that an exception occurs in okHttp Connection.upgradeToTls() when a handshake is forced. An exception I get: 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.

The following code creates an SSLContext that works like a charm when creating an SSLSocketFactory that does not throw any exceptions:

 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(); } 

The problem is that I am trying to completely remove all the Apache HttpClient dependencies from my application. The main Apache HttpClient code for creating an SSLContext seems simple enough, but I obviously missed something because I cannot configure my SSLContext to match this.

Can anyone create an SSLContext implementation that does what I want without using Apache HttpClient?

+93
android ssl android-networking
Aug 26 '14 at 15:10
source share
7 answers

Just in case, when someone falls here, the solution (only) that worked for me creates OkHttpClient , as described here .

Here is the code:

 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); } } 
+215
Sep 23 '14 at 10:33
source

The following method is deprecated

 sslSocketFactory(SSLSocketFactory sslSocketFactory) 

Consider upgrading to

 sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager) 
+13
Aug 30 '16 at 12:44
source

Update OkHttp 3.0, the getAcceptedIssuers() function should return an empty array instead of null .

+11
Apr 16 '16 at 9:09
source

SSLSocketFactory does not provide its X509TrustManager, which is the field OkHttp needs to build a clean certificate chain. Instead, this method should use reflection to retrieve the trust manager. Applications should prefer to call sslSocketFactory (SSLSocketFactory, X509TrustManager) to avoid this reflection.

Source: OkHttp documentation

 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[]{}; } }); 
+11
Nov 21 '16 at 6:52
source

This is the sonxurxo solution in Kotlin, if anyone needs it.

 private fun getUnsafeOkHttpClient(): OkHttpClient { // Create a trust manager that does not validate certificate chains val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager { override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) { } override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) { } override fun getAcceptedIssuers() = arrayOf<X509Certificate>() }) // Install the all-trusting trust manager val sslContext = SSLContext.getInstance("SSL") sslContext.init(null, trustAllCerts, java.security.SecureRandom()) // Create an ssl socket factory with our all-trusting manager val sslSocketFactory = sslContext.socketFactory return OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager) .hostnameVerifier { _, _ -> true }.build() } 
+3
May 17 '19 at 22:39
source

This is a Scala solution, if anyone needs it

 def anUnsafeOkHttpClient(): OkHttpClient = { val manager: TrustManager = new X509TrustManager() { override def checkClientTrusted(x509Certificates: Array[X509Certificate], s: String) = {} override def checkServerTrusted(x509Certificates: Array[X509Certificate], s: String) = {} override def getAcceptedIssuers = Seq.empty[X509Certificate].toArray } val trustAllCertificates = Seq(manager).toArray val sslContext = SSLContext.getInstance("SSL") sslContext.init(null, trustAllCertificates, new java.security.SecureRandom()) val sslSocketFactory = sslContext.getSocketFactory() val okBuilder = new OkHttpClient.Builder() okBuilder.sslSocketFactory(sslSocketFactory, trustAllCertificates(0).asInstanceOf[X509TrustManager]) okBuilder.hostnameVerifier(new NoopHostnameVerifier) okBuilder.build() 

}

0
Aug 01 '19 at 8:40
source

You should not look at redefining certificate verification in code! If you need to conduct testing, use an internal / test CA and install the CA root certificate on the device or emulator. You can use BurpSuite or Charles Proxy if you do not know how to configure CA.

-6
Apr 03 '15 at 19:19
source



All Articles