GithubHelp home page GithubHelp logo

cgrcnr / react-native-ssl-public-key-pinning Goto Github PK

View Code? Open in Web Editor NEW

This project forked from frw/react-native-ssl-public-key-pinning

0.0 0.0 0.0 1.33 MB

Simple and secure SSL public key pinning for React Native. No native configuration needed, set up in <5 minutes.

License: MIT License

JavaScript 11.39% Ruby 8.87% C 0.24% Objective-C 6.08% Java 30.76% TypeScript 32.69% Objective-C++ 9.80% Swift 0.17%

react-native-ssl-public-key-pinning's Introduction

react-native-ssl-public-key-pinning

MIT License Package Version CI GitHub Repo stars

Simple and secure SSL public key pinning for React Native. Uses OkHttp CertificatePinner on Android and TrustKit on iOS.

🔍Overview

  • ✅ 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.

🧰Installation

React Native

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 ..

Expo

npx expo install react-native-ssl-public-key-pinning
npx expo prebuild

🚀Usage

  1. Retrieve the base64-encoded SHA-256 public key hash of the certificates you want to pin. More details on how to do this
  2. Call initializeSslPinning as early as possible in your App entry point with your SSL pinning configuration.
  3. All network requests in your app should now have SSL pinning enabled!

Example

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 Reference

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.

⚙️Options

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. Note that at least two pins are needed per domain on iOS.

📝Additional Notes

  • 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 or XMLHttpRequest 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. Further, TrustKit (native iOS library) enforces two pins which will cause initializeSslPinning to throw an exception if only one pin is provided.
  • You can also implement an OTA update mechanism through libraries like react-native-code-push or expo-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.

🤔FAQ

How do I retrieve the base64-encoded SHA-256 public key hash of my certificates?

OpenSSL CLI

Server

Run the following command, replacing <hostname> with your server's hostname.

echo | openssl s_client -servername <hostname> -connect <hostname>:443 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | openssl enc -base64

Certificate file

openssl x509 -in certificate.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

SSL Labs

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.

ssllabs

How do I ensure that everything is set up correctly?

An easy way to test you've set everything up correctly is by temporarily providing the wrong public key hashes to initializeSslPinning. For example:

await initializeSslPinning({
  'google.com': {
    includeSubdomains: true,
    publicKeyHashes: [
      'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
      'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=',
    ],
  },
});

// ...

// This request should fail with an error
const response = await fetch('google.com');

Any requests you make to the pinned domain should fail since the server is not providing certificates that match your hashes. You can then switch back to the correct public key hashes while leaving everything else the same, and once you ensure the requests succeed again you'll know you've set it all up correctly!

📚References

🤝Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

react-native-ssl-public-key-pinning's People

Contributors

dependabot[bot] avatar frw avatar rikur avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.