question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

SSLSocketFactory with Client Certificate works fine with okhttp2 but not with okhttp3

See original GitHub issue

Here’s how I created the SSLSocketFactory that works fine with okhttp2.x but not with okhttp3:

public SSLSocketFactory createSslSocketFactory() {
    try {
      String base64PKCS12 = "****';
      String certPassword = "****";

      InputStream is = new ByteArrayInputStream(base64PKCS12.getBytes());
      Base64InputStream b64is = new Base64InputStream(is, Base64.DEFAULT);

      char[] tableauCertPassword = certPassword.toCharArray();

      // Import PKCS12 in KeyStore
      KeyStore appKeyStore = KeyStore.getInstance("PKCS12");
      appKeyStore.load(b64is, tableauCertPassword);

      is.close();
      b64is.close();

      // Building SSL context for future use
      KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
      keyManagerFactory.init(appKeyStore, tableauCertPassword);
      KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();

      // Add Trustmanager
      KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
      InputStream instream = app.getResources().openRawResource(R.raw.truststore);
      trustStore.load(instream, "*****".toCharArray());
      instream.close();

      TrustManagerFactory tmf =
          TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      tmf.init(trustStore);
      TrustManager[] managers = tmf.getTrustManagers();

      SSLContext context = SSLContext.getInstance("TLS");
      context.init(keyManagers, managers, null);

      return context.getSocketFactory();
    } catch (Exception e) {
      Timber.e(e, "SSLSocket creation exception %s", e.getMessage());
      throw new AssertionError(e);
    }
  }

With okhttp3 i have tried this, as @swankjesse did in : exemple CutomTust [https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/CustomTrust.java], but in my case I have to use TrustStore :


private KeyManager[] keyManagers;

  OkHttpClient provideOkHttpClient(Application app) {
    X509TrustManager trustManager = trustManagerForCertificates(app);
    SSLContext sslContext = null;
    try {
      sslContext = SSLContext.getInstance("TLS");
      sslContext.init(keyManagers, new TrustManager[] { trustManager }, null);
    } catch (GeneralSecurityException e) {
      throw new RuntimeException(e);
    }

    return new OkHttpClient.Builder()//
        .sslSocketFactory(sslContext.getSocketFactory(),trustManager)//
        .addInterceptor(new HostSelectionInterceptor()).build();
  }

  public  X509TrustManager trustManagerForCertificates(Application app) {

    try {
      String base64PKCS12 = "**";
      String certPassword = "**";

      InputStream is = new ByteArrayInputStream(base64PKCS12.getBytes());
      Base64InputStream b64is = new Base64InputStream(is, Base64.DEFAULT);

      char[] tableauCertPassword = certPassword.toCharArray();

      // Import PKCS12 in KeyStore
      KeyStore appKeyStore = KeyStore.getInstance("PKCS12");
      appKeyStore.load(b64is, tableauCertPassword);

      is.close();
      b64is.close();

Here is where I manage the TRUSTSTORE

  // Add Trustmanager
      KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
      InputStream instream = app.getResources().openRawResource(R.raw.truststore);
      trustStore.load(instream, "****".toCharArray());
      instream.close();

// Building SSL context for future use
      KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
      keyManagerFactory.init(appKeyStore, tableauCertPassword);
      keyManagers = keyManagerFactory.getKeyManagers();



     TrustManagerFactory tmf =
          TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      tmf.init(trustStore );

      TrustManager[] trustManagers = tmf.getTrustManagers();

      if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
        throw new IllegalStateException(
            "Unexpected default trust managers:" + Arrays.toString(trustManagers));
      }
      return (X509TrustManager) trustManagers[0];
    } catch (Exception e) {
      Timber.e(e, "SSLSocket creation exception %s", e.getMessage());
      throw new AssertionError(e);
    }
  }

Thanks in advance

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:16 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
mboukadircommented, Aug 19, 2016

I would love to contribute in solving the problem. However, I cannot share the client certificates, due to confidentiality issues. In addition the company I am working does not allow running tests on their servers with mocked certificates. Keep in mind that in order to fix this bug, I am ready to help out.

0reactions
vasiledoecommented, Oct 27, 2018

@bjornson any solutions?

Read more comments on GitHub >

github_iconTop Results From Across the Web

how to add SSL certificates to okHttp mutual TLS connection?
Looking at your curl command and java code I see that they are not configured the same. Let's first have a look at...
Read more >
Trusting All Certificates in OkHttp | Baeldung
In this short article, we've seen how to create and configure an OkHttpClient to trust all certificates. Of course, trusting all certificates is...
Read more >
Self-Signed Certificates with OkHttp – the Right Way
Even for your test environment. The good news is, it's just as easy to fix the right way by adding trust for your...
Read more >
Accepting self-signed certificates in OKHttp3 - Blog
Learn how to generate a self-signed certificate, and how to accept it in HTTPS connections using OkHttp3 in an Android app.
Read more >
HTTPS - OkHttp - Square Open Source
A client that wants to maximize connectivity would include obsolete TLS ... COMPATIBLE_TLS is a secure configuration that connects to secure–but not ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found