Now that SSLSocketFactory is deprecated on Android, what would be the best way to handle Client Certificate Authentication?

35,018

Solution 1

Apparently, there are two SSLSocketFactory classes. HttpClient has its own one, and that is deprecated along with the rest of HttpClient. However, everybody else will be using the more conventional javax.net.ssl edition of SSLSocketFactory, which is not deprecated (thank $DEITY).

Solution 2

if you are using https, you have to use a valid certificate. During your dev stage you have to trust the certificate, how? sslSocketFactory(SSLSocketFactory sslSocketFactory) is deprecated and it's replaced by sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager), you have to update your gradle file the piece of code below will help you to get a trusted OkHttpClient that trusts any ssl certificate.

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
    throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { trustManager }, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory, trustManager);

Solution 3

Look this i find some solution and in my side is work well. Check how i've integrated..

OkHttpClient.Builder client = new OkHttpClient.Builder();

add here all properties for client instance

. . .

and add those line of code for sslSocketFactory:

 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) {
                    }

                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                    }

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

        client.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
        client.hostnameVerifier((hostname, session) -> true);
    } catch (Exception e) {
        throw new RuntimeException(e);
  }
Share:
35,018

Related videos on Youtube

TheYann
Author by

TheYann

I'm just a geek

Updated on January 29, 2020

Comments

  • TheYann
    TheYann over 4 years

    I am working on an Android app that requires Client Certificate Authentication (with PKCS 12 files). Following the deprecation of all that's apache.http.*, we have started a pretty big work of refactoring on our network layer, and we have decided to go with OkHttp as a replacement, and so far I like that very much.

    However, I haven't found any other way to handle client certificate auth without using SSLSocketFactory, with OkHttp or anything else for that matter. So what would be the best course of action in this particular case? Is there another way with OkHttp to handle this sort of authentication?

    • CommonsWare
      CommonsWare almost 9 years
      SSLSocketFactory is not deprecated, either in the current shipping versions of Android or in the M Developer Preview.
    • TheYann
      TheYann almost 9 years
      Oh my god you are absolutely right, I never realised there were 2 classes SSLSocketFactory! org.apache.http.conn.ssl.SSLSocketFactory is deprecated but javax.net.ssl.SSLSocketFactory is not! Thanks a lot for this enlightenment.
    • CommonsWare
      CommonsWare almost 9 years
      Conversely, I had not realized that HttpClient had their own SSLSocketFactory class. :-)
  • tryp
    tryp about 7 years
    Thanks, the deprecated warning is removed simply by adding the trust manager.
  • IgorGanapolsky
    IgorGanapolsky almost 6 years
    I still get SSLHandshakeException: connection closed by peer
  • user2167877
    user2167877 almost 6 years
    I'm not expert in NTLM, but may you need to use an external library as JCIFS.
  • bompf
    bompf about 5 years
    Trusting every certificate and hostname is a bad idea.
  • Jorgesys
    Jorgesys over 4 years
    Security hole! This is not recommended