Open In App

How to implement SSL Certificate Pinning while using React Native ?

Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will be learning how to secure your react-native application by implementing SSL certificate pinning. 

Prerequisites:

  • Basic knowledge of react native.
  • The latest version of Node js and Android studio.
  • Java SE Development Kit (JDK). A minimum of Java 8

Approach: The first question that will come into your mind would be why we need SSL Certificate Pinning. Below are the points why we need SSL certificate pinning for our React Native application.

  • SSL Pinning provides security against eavesdropping, When data is transmitted over a network, the man-in-the-middle(hacker) can take advantage of an insecure connection, the hacker can seek to be in the middle of communication between the app and the backend server with malicious intentions and can steal the crucial information transmitted over the network. 
  • For example: If your application is receiving payment from customers then the hacker and eavesdrop on the credit card credentials. In this situation, SSL pinning plays a major role.
  • When you navigate to a secure website, you see a lock sign on the top left side (see the screenshot below) which signifies that the connection with this website is protected. Each protected site is identified by a certificate that is recognized by your browser. 

 

Implementing SSL certificate pinning:

Creating Application: Follow the below steps to create a React Native application:

Step 1: Open your terminal and write the following command.

npx react-native init AwesomeProject

Step 2: Now go into your project folder i.e. Project

cd AwesomeProject

Project Structure:

 

Now, Go to AwesomeProject >> android and create a new file named local.properties in this directory.

sdk.dir = /home/<!-- your pc name here -->/Android/Sdk

 

For example:

sdk.dir = /home/ACER/Android/Sdk

Note: Here, ‘ACER’ is my computer name, replace this with your computer name.

Run your application on an emulator:

npx react-native run-android

 

Run the following command to install react-native-ssl-pinning package:

npm install react-native-ssl-pinning

We will be using JSONPlaceholder API for implementing SSL pinning. To get an SSL certificate, run the following command in your terminal:

openssl s_client -servername jsonplaceholder.typicode.com -connect jsonplaceholder.typicode.com:443 </dev/null | sed -n -e ‘/-.BEGIN/,/-.END/ p’ > mycert.pem 

This command will generate mycer.pem file which is the certificate for jsonplaceholder. But we need this file in .cer format. 

Now, to convert .pem to .cer, run the following command:

openssl x509 -in mycert.pem -outform der -out mycert.cer

Go to the following directory in your project: 

AwesomeProject >> android >> app >> src >> main >> assets

and copy the mycert.cer file in this directory.

Code: Now, let’s write the code to fetch data from the API:

  • App.js

Javascript




import React from 'react';
 
// importing basic react-native components
// required in our application
import { TouchableOpacity, StyleSheet, Text, View } from 'react-native';
import { useState } from 'react';
 
// fetch is imported from the package we
// installed in the previous steps
import { fetch } from 'react-native-ssl-pinning';
 
const App = () => {
    const [randomText, setRandomText] = useState("");
    const secureFetchData = () => {
        //fetching from the jsonplaceholder URL
        const URL = 'https://jsonplaceholder.typicode.com/posts/1';
        fetch(URL, {
            method: 'GET',
            timeoutInterval: 10000,
            // passing the mycert certificate that we
            // generated in the previous steps
             
            // The certs property is an array of certificates,
            // we are passing mycert as our certificate
            // for ssl pinning
            sslPinning: {
                certs: ['mycert'],
            },
        })
            .then(response => response.json())
            .then(result => {
                // Printing the response from server
                console.log(result);
 
                // Updating the state value to the data fetched
                // result is an object returned by the
                // server .body is a property of result object
                // for more detail see the screenshot appended
                // below this code
                setRandomText(result.body);
            })
            .catch(err => {
                //handling any error
                console.log(`error: ${err}`);
            });
    };
 
    // creating a touchable button to fetch data
    return (
        <View style={styles.container}>
            <Text style={styles.text}>{randomText}</Text>
            <TouchableOpacity style={styles.button}
                onPress={secureFetchData}>
                <Text style={styles.text}>
                    Fetch secured data
                </Text>
            </TouchableOpacity>
        </View>
    );
};
 
// Stylesheet to style the react-native components.
const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    },
    text: {
        fontSize: 25,
    },
    button: {
        alignItems: 'center',
        backgroundColor: 'green',
        paddingVertical: 10,
        paddingHorizontal: 20,
        borderRadius: 4,
        marginVertical: 12,
    },
});
 
export default App;


Code Explanation:

  • fetch method is imported from react-native-ssl-pinning. getData function fetching data from jsonplaceholder.typicode.com using this fetch method. 
  • This fetch method takes an SSL Pinning option, which is an object with a cert (cert stands for certificate) property. The cert property is an array of all our certificates. We passed “mycert” in this array, “mycert” is the certificate we generated in the previous steps, which is a trusted certificate.
  • Thus the connection will be established successfully and we will be able to fetch data from jsonplaceholder.typicode.com.

To test our code, we will need to rebuild our application: 

Steps to run the application: Run the following command to rebuild the application:

npx react-native run-android

Now click on the Fetch secured Data button.

Output:

output

Console Output: 

console output

Conclusion: As you can see the data is successfully fetched. If we would have passed an expired certificate or an Invalid certificate then the server would not respond to our fetch request as the connection could be breached. 



Last Updated : 26 Dec, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads