How to encrypt and decrypt data between a standalone react application and a Laravel application using Rsa encryption
Published: 2023-09-12 07:01:18



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:

```bash
# Using Yarn
yarn add jsencrypt

# Using npm
npm install jsencrypt
```
**Step 4: Add encryption Code in app.tsx and form to send encrypted data to laravel backend**

```javascript
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;
```

**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 
```bash
composer require phpseclib/phpseclib:~3.0
```

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

```php
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
        ]
    ]);
});
```

**Step 7: Start your React and Laravel development server**
 
```bash
#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
```
**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!