Git Product home page Git Product logo

rn-mutual-tls's Introduction

react-native-mutual-tls

Mutual TLS authentication for HTTP requests in React Native.

The client certificate and associated password are stored securely in the native Keychain.

Once the module is set up, it applies to all normal react-native HTTP requests (e.g. through fetch, XMLHttpRequest, or any library that uses these) for HTTPS connections that ask for a client certificate. There is no overhead for connections that do not request a client certificate.

Only iOS is supported at this time, but pull requests are welcome if anyone wants to help add support for Android.

Getting started

Install it as a dependency for your react-native project. You'll probably also need the native module for Keychain unless you have some other way of getting the secrets into the keychain:

yarn add react-native-mutual-tls
yarn add react-native-keychain
npx pod-install

Prerequisites

In order to use this module, you'll need a client certificate encoded as a p12 file, encrypted with a password.

The example project in this repository uses this test certificate from badssl.com, but you'll need to provide your own.

The certificate and password are expected to be loaded into the native Keychain at runtime, because it's considered bad practice to hard-code them or embed them as static resources in your app bundle. You'll need to expect the user to supply these, or download them at runtime from some secure source.

Usage

Import the MutualTLS module, as well as the Keychain module.

import MutualTLS from 'react-native-mutual-tls';
import Keychain from 'react-native-keychain';

Optionally, set up debug information and errors from this module to go to the console for troubleshooting purposes. You could also provide different functions here if you wanted to do something else with the events.

If you don't do this, there will be no logging of such events.

MutualTLS.onDebug(console.debug);
MutualTLS.onError(console.error);

Before making a request, you'll need to load the secrets into the Keychain.

Refer to the documentation for the Keychain module for more information about managing secrets in the keychain, how to clear the secrets, and how to check whether the secrets are already loaded to avoid doing work to load them every time the app starts.

const myP12DataBase64 = "YOUR P12 FILE ENCODED AS BASE64 GOES HERE";
const myPassword = "THE PASSWORD TO DECRYPT THE P12 FILE GOES HERE";

await Promise.all([
  Keychain.setGenericPassword('', myP12DataBase64, { service: "my-tls.client.p12" }),
  Keychain.setGenericPassword('', myPassword, { service: "my-tls.client.p12.password" }),
]);

Next you need to call MutualTLS.configure to tell the module where to find the secrets in the keychain.

MutualTLS will not pre-load the secrets when configured - they will be loaded on the fly each time they are needed by an authentication challenge, so there is no need to call MutualTLS.configure more than once even if the secret values change.

If you do not call MutualTLS.configure, then the following defaults are used:

  • keychainServiceForP12: mutual-tls.client.p12
  • keychainServiceForPassword: mutual-tls.client.p12.password

If you're using MutualTLS in a test environment with a proxied connection where the server name does not match the server name in the server certificate, you can also set the insecureDisableVerifyServerInRootDomain option to the root domain for which you want to insecurely trust all subdomains. For example, setting it to example.com would let you insecurely trust servers at a domain like bad.example.com. DO NOT USE THIS SETTING IN A PRODUCTION ENVIRONMENT, as it defeats server authentication security features which form the other half of the "mutual" part of Mutual TLS.

// Use the same service names that were used in `Keychain.setGenericPassword`
await MutualTLS.configure({
  keychainServiceForP12: 'my-tls.client.p12',
  keychainServiceForPassword: 'my-tls.client.p12.password',
});

Assuming you've done all that setup, then you're ready to make secure Mutual TLS requests with a server that is configured to trust the client certificate you provided.

As stated before, any normal react-native HTTP request (e.g. through fetch, XMLHttpRequest, or any library that uses these) for HTTPS connections that ask for a client certificate will work, with no special options needed at request time.

const response = await fetch('https://my-secure.example.com/');

To see and run a fully working demonstration using https://client.badssl.com/ as the test server, see the example project in this repository.

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.