Encrypt String in Python, & Decrypt in React | Explained with Code


Introduction

In today's interconnected digital world, secure communication and data transfer are more crucial than ever. As developers, we often find ourselves working with different technologies and platforms to build robust and scalable applications.

One common challenge we face is securely transferring String data between different programming environments, such as between a Python(back-end) and a React(front-end). Ensuring data integrity and confidentiality is paramount, and that's where encryption comes into play.

In this article, we will explore a practical solution for encrypting String data in Python and subsequently decrypting it in a React application. This tutorial, will provide step-by-step guidance on implementing AES encryption with PBKDF2 for key derivation.

Whether you're a seasoned developer or just starting your journey in web development, this article will equip you with the knowledge and tools you need to ensure secure communication between your Python and React applications. So, let's get started on our journey towards a more secure data transfer process!

Encrypting String Data in Python

In this section, we will focus on encrypting string data in Python using a combination of AES encryption, PBKDF2 key derivation, and the cryptography library. We will understand how to encrypt a given plaintext string and securely generate a key for decryption.

To begin, let's first install the required Python library, cryptography, by running the following command in our Python environment, which is typically done using a command-line interface or terminal:

pip install cryptography

This will install the cryptography library in our Python environment, making it available for use in our project.

Let's assume we are writing all the Python code for encryption in a single file. Now, let's dive into the code.

We'll start by importing the necessary modules from the cryptography library, along with os for generating random values and base64 for encoding:

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.padding import PKCS7
from cryptography.hazmat.backends import default_backend
from base64 import b64encode
import os

Next, we'll define a function called encrypt, which takes two parameters: the derived key and the plaintext string to be encrypted. This function is responsible for performing the encryption process:

def encrypt(key, plaintext):
    iv = os.urandom(16)
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()

    padder = PKCS7(128).padder()
    padded_plaintext = padder.update(plaintext.encode("utf-8")) + padder.finalize()

    ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize()
    return b64encode(iv + ciphertext).decode("utf-8")

In this function, we first generate a random 16-byte initialization vector (IV) using os.urandom(). Then, we create a cipher object with the AES algorithm, using the derived key and the CBC mode. We also initialize an encryptor using the cipher.encryptor() method.

To ensure that the plaintext string is a multiple of the block size (16 bytes for AES), we apply PKCS7 padding using the PKCS7 class from the cryptography library. We then encrypt the padded plaintext with the encryptor and combine the IV and ciphertext. Finally, we return the base64-encoded encrypted data as a string.

With the encrypt function defined, we can now generate a derived key using the PBKDF2 key derivation function:

backend = default_backend()
salt = os.urandom(16)
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, backend=backend)
key = kdf.derive(b"your-password")

Here, we create a random salt and use the PBKDF2HMAC function with SHA-256 hashing, a 32-byte key length, and 100,000 iterations. We then derive the key using our chosen password.

Finally, we can encrypt our plaintext string ("Hello World!") using the derived key and print the encrypted data and base64-encoded key:

encrypted_data = encrypt(key, "Hello World!")
key_to_decrypt = b64encode(key).decode("utf-8")

# Send this Encrypted Data and the Key to be used for Decription to React
print(encrypted_data)
print(key_to_decrypt)

Now we have successfully encrypted a plaintext string in Python and generated a key that can be used for decryption. Here is the complete code in the Python file:

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.padding import PKCS7
from cryptography.hazmat.backends import default_backend
from base64 import b64encode
import os

def encrypt(key, plaintext):
    iv = os.urandom(16)
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()

    padder = PKCS7(128).padder()
    padded_plaintext = padder.update(plaintext.encode("utf-8")) + padder.finalize()

    ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize()
    return b64encode(iv + ciphertext).decode("utf-8")

backend = default_backend()
salt = os.urandom(16)
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, backend=backend)
key = kdf.derive(b"your-password")


encrypted_data = encrypt(key, "Hello World!")
key_to_decrypt = b64encode(key).decode("utf-8")

# Send this Encrypted Data and the Key to be used for Decription to React
print(encrypted_data)
print(key_to_decrypt)

The provided Python code demonstrates how to encrypt a plaintext string using the cryptography library, along with AES encryption and PBKDF2 for key derivation. The code also generates and prints the encrypted data and the key to be used for decryption. Running this code generated the following random Output -

ou78qkeSvL27XtyUaoq93ugzZw1KKMFjkcCHq7oxFzc=
8QrAv3Xr6QzFSwHYEGjJsaMI45P8yPPN1BWXRqJ+80M=

As can be seen from the Output above, the encrypted_data and the key_to_decrypt(base64Key) is generated. Everytime this Python code is executed, new data will be generated. Now this data - encrypted_data and the key_to_decrypt can be sent to React(Front-end) using an API, sockets, or any other ways.

In the next section of the article, we will cover the decryption process in React, demonstrating how to securely decrypt this encrypted data in React(front-end) using the key.

Decrypting the Encrypted String data in React

In this section, we will learn how to decrypt the encrypted string data in a React application using the crypto-js library. This library provides cryptographic functions such as AES encryption and decryption, as well as various encoding and decoding utilities.

Once we receive the Encrypted String data and Base64 key from Python through API, Sockets, or some different way, we need to go to the React Project folder and begin the decryption process(as required). In this section, we will be writing our code in app.js file.

First, let's install the crypto-js library in your React project by running the following command:

npm install crypto-js

Next, we will import the required modules from the crypto-js library, along with the useState and useEffect hooks from the React library:

import React, { useState, useEffect } from "react";
import CryptoJS from "crypto-js";

Inside the App component, we will create a state variable called decryptedData and initialize it with an empty string:

const [decryptedData, setDecryptedData] = useState("");

In the useEffect hook, we will define the decryptData function which will handle the decryption process. To do this, we need the encryptedData and the base64Key that we received from the Python script.

const encryptedData = "ou78qkeSvL27XtyUaoq93ugzZw1KKMFjkcCHq7oxFzc=";
const base64Key = "8QrAv3Xr6QzFSwHYEGjJsaMI45P8yPPN1BWXRqJ+80M=";

Now, let's define the decryptData function:

  1. Parse the base64Key to create the key object.
  2. Parse the encryptedData and extract the iv and ciphertext.
  3. Use the CryptoJS.AES.decrypt function to decrypt the ciphertext using the key and iv.
  4. Convert the decrypted bytes to a UTF-8 string.
const decryptData = () => {
  const key = CryptoJS.enc.Base64.parse(base64Key);

  const dataBytes = CryptoJS.enc.Base64.parse(encryptedData);
  const iv = CryptoJS.lib.WordArray.create(dataBytes.words.slice(0, 4));
  const ciphertext = CryptoJS.lib.WordArray.create(dataBytes.words.slice(4));

  const decryptedBytes = CryptoJS.AES.decrypt({ ciphertext }, key, { iv });
  const decryptedText = CryptoJS.enc.Utf8.stringify(decryptedBytes);

  console.log(decryptedText);
  setDecryptedData(decryptedText);
};

Finally, call the decryptData function inside the useEffect hook:

useEffect(() => {
  decryptData();
}, []);

In the return statement, display the decrypted data on the screen:

return (
  <div className="App">
    Decrypted data: {decryptedData}
  </div>
);

That's it! The React code demonstrates how to decrypt the encrypted string data received from the Python script using the crypto-js library. Once the decryption is complete, the decrypted data will be displayed on the screen. Here is the complete React Code -

import React, { useState, useEffect } from "react";
import "./App.css";

import CryptoJS from "crypto-js";

function App() {
  const [decryptedData, setDecryptedData] = useState("");

  useEffect(() => {
    const encryptedData = "ou78qkeSvL27XtyUaoq93ugzZw1KKMFjkcCHq7oxFzc=";
    const base64Key = "8QrAv3Xr6QzFSwHYEGjJsaMI45P8yPPN1BWXRqJ+80M=";

    const decryptData = () => {
      const key = CryptoJS.enc.Base64.parse(base64Key);

      const dataBytes = CryptoJS.enc.Base64.parse(encryptedData);
      const iv = CryptoJS.lib.WordArray.create(dataBytes.words.slice(0, 4));
      const ciphertext = CryptoJS.lib.WordArray.create(
        dataBytes.words.slice(4)
      );

      const decryptedBytes = CryptoJS.AES.decrypt({ ciphertext }, key, { iv });
      const decryptedText = CryptoJS.enc.Utf8.stringify(decryptedBytes);

      console.log(decryptedText);
      setDecryptedData(decryptedText);
    };

    decryptData();
  }, []);

  return (
    <div className="App">
      Decrypted data: {decryptedData}
    </div>
  );
}

export default App;

So, when we run the above code, we get the following Output -

Hello World!

Conclusion

We've explored a practical and efficient approach to encrypting string data in Python and decrypting it in a React application. This article demonstrated how to use the cryptography library in Python for encryption, and the crypto-js library in React for decryption. By leveraging these tools, developers can ensure secure data transfer between their back-end Python services and front-end React applications.

Through step-by-step code examples, we've illustrated the process of generating an encryption key, and encrypting a string in Python. The React app then decrypts this data using a shared key, ensuring data integrity and confidentiality.

With this knowledge, you can now confidently implement encryption and decryption techniques to safeguard sensitive data in your Python and React projects. As a developer, it's essential to stay informed about security best practices and to continually refine your skills in order to build robust, secure applications for your users.

I hope you found this article helpful.

Encrypt String in Python, & Decrypt in React - Explained with Code

You may also like to Explore -

float data type, float() function, & float methods – Python

Convert Class Component to Function(Arrow) Component – React

Sort Dictionaries by Key, or Value, in Python – Asc, Desc

Cheers!

Happy Coding.

About the Author

This article was authored by Rawnak.