Simple and secure SSL public key pinning for React Native. Uses OkHttp CertificatePinner on Android and TrustKit on iOS.
- ✅ Supports SSL public key pinning using the base64-encoded SHA-256 hash of a certificate's Subject Public Key Info.
- ✅ No native configuration needed. Simply install and configure through the provided JS API.
- ✅ No modification of existing network request code needed. All network requests done through the standard Networking APIs will have the certificate pinning configuration automatically enabled after initialization.
- ✅ Compatible with Flipper Network plugin for easier debugging of network requests.
npm install react-native-ssl-public-key-pinning
OR for Yarn use:
yarn add react-native-ssl-public-key-pinning
Before building for iOS, make sure to run the following commands:
cd ios && pod install && cd ..
npx expo install react-native-ssl-public-key-pinning
npx expo prebuild
- Retrieve the base64-encoded SHA-256 public key hash of the certificates you want to pin. More details on how to do this
- Call
initializeSslPinning
as early as possible in your App entry point with your SSL pinning configuration. - All network requests in your app should now have SSL pinning enabled!
import { initializeSslPinning } from 'react-native-ssl-public-key-pinning';
await initializeSslPinning({
'google.com': {
includeSubdomains: true,
publicKeyHashes: [
'CLOmM1/OXvSPjw5UOYbAf9GKOxImEp9hhku9W90fHMk=',
'hxqRlPTu1bMS/0DITB1SSu0vd4u/8l8TjPgfaAp63Gc=',
'Vfd95BwDeSQo+NUYxVEEIlvkOlWY2SalKK1lPhzOx78=',
'QXnt2YHvdHR3tJYmQIr0Paosp6t/nggsEGD4QJZ3Q0g=',
'mEflZT5enoR1FuXLgYYGqnVEoZvmf9c2bVBpiOjYQ0c=',
],
},
});
// ...
// This request will have public key pinning enabled
const response = await fetch('google.com');
API | Description |
---|---|
isSslPinningAvailable(): boolean |
Returns whether the SslPublicKeyPinning NativeModule is available on the current app installation. Useful if you're using Expo Go and want to avoid initializing pinning if it's not available. |
initializeSslPinning(options: PinningOptions): Promise<void> |
Initializes and enables SSL public key pinning for the domains and options you specify. |
disableSslPinning(): Promise<void> |
Disables SSL public key pinning. |
Option | Type | Mandatory | Description |
---|---|---|---|
includeSubdomains |
boolean |
No | Whether all subdomains of the specified domain should also be pinned. Defaults to false . |
publicKeyHashes |
string[] |
Yes | An array of SSL pins, where each pin is the base64-encoded SHA-256 hash of a certificate's Subject Public Key Info. |
- On iOS, SSL/TLS sessions are cached. If a connection to your site previously succeeded, setting a pinning configuration that should fail the following request would not actually fail it since the previous session is used. You will need to restart your app to clear out this cache.
- Third-party libraries that use
fetch
orXMLHttpRequest
would also be affected by the pinning (e.g.axios
). However, native libraries that implement their own methods of performing network requests would not be affected by the pinning configuration. - To prevent accidentally locking users out of your site, ensure you have at least one backup pin and have procedures in place to transition to using the backup pin if your primary pin can no longer be used. Read more about this here.
- You can also implement an OTA update mechanism through some libraries that enable this capability (e.g.
react-native-code-push
orexpo-updates
). Doing this will help ensure your key hashes are up to date without needing users to download a new version from the Play Store/App Store since all pinning configurations are done through the JS API.
How do I retrieve the base64-encoded SHA-256 public key hash of my certificates?
Run the following command, replacing <hostname>
with your server's hostname.
openssl s_client -servername <hostname> -connect <hostname>:443 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
openssl x509 -in certificate.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
If your site is accessible publicly, you can use https://www.ssllabs.com/ssltest/index.html to retrieve the public key hash of your certificates.
See the contributing guide to learn how to contribute to the repository and the development workflow.