DEV Community

Gideon Iyinoluwa Owolabi
Gideon Iyinoluwa Owolabi

Posted on

How to encrypt and decrypt data between a standalone react application and a Laravel application using Rsa encryption

RSA encryption is a powerful tool for securing data transmission between applications. It relies on a pair of keys - a public key for encryption and a private key for decryption. In this tutorial, I will guide you through implementing RSA encryption to send data securely between a standalone React frontend application and a Laravel backend.

Step 1: Generate RSA Key Pairs
Before we dive into the code, we need to generate the key pairs. You can do this by visiting https://cryptotools.net/rsagen. Keep the private key secure, as it will be used for decryption.

Step 2: Set Up Your Projects
Create two separate projects - a fresh React project for the frontend and a fresh Laravel project for the backend.

Step 3: Install JSEncrypt in React

In your React project, We will make use of https://www.npmjs.com/package/jsencrypt library for encrypting our data. Install JSEncrypt using either of the following commands:

# Using Yarn
yarn add jsencrypt

# Using npm
npm install jsencrypt
Enter fullscreen mode Exit fullscreen mode

Step 4: Add encryption Code in app.tsx and form to send encrypted data to laravel backend

import { useRef, useState } from "react";
import JSEncrypt from "jsencrypt";

type Result = {
    message?: string;
    data?: {
      encrypted: string;
      decrypted: object;
    };
  };
function App() {
  const nameRef = useRef<HTMLInputElement>(null);
  const phoneRef = useRef<HTMLInputElement>(null);
  const [result, setResult] = useState<Result>({});

  // Encrypt request data
  const encryptRequestData = (data: string) => {
    let KEY = `-----BEGIN PUBLIC KEY-----
MIICITANBgkqhkiG9w0BAQEFAAOCAg4AMIICCQKCAgBoLTFCc40LxJcidVs6/WFw
    // ... [Your public key]
    -----END PUBLIC KEY-----`;
    let encryptor = new JSEncrypt();
    encryptor.setPublicKey(KEY);
    return encryptor.encrypt(data);
  };

  const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    try {
      e.preventDefault();
      setResult({});
      if (!nameRef.current?.value || !phoneRef.current?.value) {
        return;
      }
      let data = JSON.stringify({
        name: nameRef.current.value,
        phone: phoneRef.current.value,
      });
      let encrypted_data = encryptRequestData(data);
      let requestBody = JSON.stringify({
        encrypted: encrypted_data,
      });

      const response = await fetch("http://127.0.0.1:8000/api/decrypt-data", {
        method: "POST",
        body: requestBody,
        headers: {
          "Content-Type": "application/json",
        },
      });
      let res = await response.json();
      setResult(res);
    } catch (err) {
      alert(String(err));
    }
  };

  return (
    <form onSubmit={onSubmit}>
      <h2>
        Simple form to demonstrate Rsa Encryption between a react and laravel
        application
      </h2>
      <label htmlFor="name">Name</label>
      <br />
      <input type="text" name="name" id="name" ref={nameRef} />
      <br />
      <br /> <label htmlFor="phone">Phone</label>
      <br />
      <input type="tel" name="phone" id="phone" ref={phoneRef} />
      <br />
      <br />
      <button type="submit">Submit</button>
      <div
        style={{ maxWidth: "500px", padding: "2px", wordWrap: "break-word" }}
      >
        <p>Encrypted: {result.data?.encrypted}</p>
        <p>Decrypted: {JSON.stringify(result.data?.decrypted)}</p>
      </div>
    </form>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Step 5: Install Phpseclib on Laravel
https://packagist.org/packages/phpseclib/phpseclib is a php library that can be used to implement rsa encryption. To install run the command

composer require phpseclib/phpseclib:~3.0
Enter fullscreen mode Exit fullscreen mode

Step 6: Create a private_key.pem file
Create a file in the storage folder of you laravel project and name it private_key.perm. Copy and paste the private key generated into the file and save

Step 6: Navigate into the your routes/api.php file
Navigate into your routes/api.php file and paste in this code

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Crypt\RSA;

Route::post("/decrypt-data", function (Request $request) {
    if (!$request->encrypted) {
        return response()->json([
            'error' => "Data is empty"
        ], 400);
    }

    $key = PublicKeyLoader::load(file_get_contents(storage_path('private_key.pem')));
    $key = $key->withPadding(RSA::ENCRYPTION_PKCS1);
    $decrypted_data = json_decode($key->decrypt(base64_decode($request->encrypted)));

    return response()->json([
        "message" => "Data Decrypted!",
        "data" => [
            "encrypted" => $request->encrypted,
            "decrypted" => $decrypted_data
        ]
    ]);
});
Enter fullscreen mode Exit fullscreen mode

Step 7: Start your React and Laravel development server

#Enter in to the root folder of your react project and start react server
npm start

#Enter into the root folder of you laravel project and start laravel server
php artisan serve
Enter fullscreen mode Exit fullscreen mode

Conclusion
With that we have been able to setup encryption and decryption between a react app and a Laravel app. You can find the complete code implementation on this GitHub repository https://github.com/gude1/RSA_ENCRYPTION

If you have any further questions or need additional assistance, don't hesitate to ask. Happy coding!

Top comments (0)