Skip to content

Instantly share code, notes, and snippets.

@omerlh
Created June 26, 2017 06:23
Show Gist options
  • Save omerlh/8ddafbcffc1cc95854d6381ac8c81476 to your computer and use it in GitHub Desktop.
Save omerlh/8ddafbcffc1cc95854d6381ac8c81476 to your computer and use it in GitHub Desktop.
import com.datatheorem.android.trustkit.TrustKit;
import com.datatheorem.android.trustkit.config.PublicKeyPin;
import javax.inject.Inject;
import okhttp3.CertificatePinner;
import okhttp3.OkHttpClient;
public class OkHttpCertPin {
private final TrustKit mTrustKit;
@Inject
public OkHttpCertPin(TrustKit trustKit)
{
mTrustKit = trustKit;
}
public OkHttpClient extend(OkHttpClient currentClient, String hostName) {
CertificatePinner.Builder certificatePinnerBuilder = new CertificatePinner.Builder();
for (PublicKeyPin key : mTrustKit.getConfiguration().getPolicyForHostname(hostName).getPublicKeyPins()) {
certificatePinnerBuilder.add(hostName, "sha256/" + key.toString());
}
return currentClient.newBuilder().certificatePinner(certificatePinnerBuilder.build()).build();
}
}
@threesquared
Copy link

Can you post your corresponding MainActivity.java as well please? Thanks!

@jnbt
Copy link

jnbt commented Jul 6, 2017

@cihadturhan
Copy link

@omerlh the article doesn't mention which react-native library uses this. Is it for any third party (like Axios) using XMLHttpRequest API or just for Fetch API?

@karthiganesan90
Copy link

@omerlh, it doesn't work for Android 6.0 version with RN 0.49.5 and we are using redux-sags to create a network request, but we can able to intercept the API's req/res using Charles. any help, Thanks.

@JaEdmuva
Copy link

@cihadturhan I think RN fetch API uses XmlHttpRequest, haven't had a look at that, and axios does use it. In any case, this works for okhttp3 in android and the corresponding in iOS (I'm not much of an iOS developer).
@karthiganesan90 yes, it does not work anymore, not like that at least, depending on the version of RN you are using.
0.54 adds back this ability through OkHttpClientFactory. I did something like this:

OkHttpClientProvider.setOkHttpClientFactory(new CustomClientFactory());

then in your factory class, override method createNewNetworkModuleClient() and you'll be able to feed the client you need to the networking module, responsible for networking.

@kyaroru
Copy link

kyaroru commented Jun 13, 2018

In order to match with @omerlh gist, here's the MainActivity.java for react native to use SSL Pinning on Android
Using RN 0.51 with Axios

package com.yourpackage;

import android.os.Bundle;

import com.facebook.react.ReactActivity;
import com.datatheorem.android.trustkit.TrustKit;
import com.facebook.react.modules.network.OkHttpClientProvider;
import okhttp3.OkHttpClient;

public class MainActivity extends ReactActivity {
    private String hostname = "your.server.com";
    private OkHttpClient currentClient;
    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "YourApp";
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TrustKit.initializeWithNetworkSecurityConfiguration(this, R.xml.network_security_config);
        currentClient = new OkHttpClient().newBuilder()
                                .sslSocketFactory(TrustKit.getInstance().getSSLSocketFactory(hostname), TrustKit.getInstance().getTrustManager(hostname))
                                .build();
        rebuildOkHtttp();
    }

    private void rebuildOkHtttp() {
        OkHttpCertPin certPin = new OkHttpCertPin(TrustKit.getInstance());
        OkHttpClient replacementClient = certPin.extend(currentClient, hostname);
        OkHttpClientProvider.replaceOkHttpClient(replacementClient);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment