
Cryptography is the practice of securing information by transforming it into an unreadable format called ciphertext, making it difficult for unauthorized individuals to access or comprehend the original information. It is an essential component of modern-day communication and information security systems.
We often need to store confidential data in the database while we are working with web based projects like Django, FastAPI, Flask, or in any other other project. But it’s not a wise idea to store that confidential data in plain text format.
To protect our confidential data, we can use cryptography. We can convert plain text to encrypted format before store to database. We can also get that data in plain text format after retrieving it from the database.
In this blog I am going to show you how to protect confidential data from vulnerabilities. We are going to use a widely used python based cryptography package with Django.
Source: https://github.com/pyca/cryptography
Install cryptography package by running below command
pip install cryptography
To encrypt and decrypt we need a key. Now we have to set a key to the .env file of your Django project.
ENCRYPTION_KEY=your_encryption_key
To create an e encryption_key we can use the below process or you can create one as you want. The key could be anything.
>>> from cryptography.fernet import Fernet
>>> key = Fernet.generate_key()
>>> key
>>> b'OeTTHNqHVsjO6aDP7YnElUpAvOyJEO_7jI7Em5_oR_E='
>>> key_string = key.decode('utf-8')
>>> key_string
>>> OeTTHNqHVsjO6aDP7YnElUpAvOyJEO_7jI7Em5_oR_E=
Copy the created key and set it to ENCRYPTION_KEY variable inside .env file.
Note: By default generate_key method returns bytes object. We need to decode it with ‘utf-8′ to get plain text.
Now load the ENCRYPTION_KEY in Django settings file from .env. To do so put the below line to settings.py file
ENCRYPTION_KEY = env("ENCRYPTION_KEY")
Now create service to encrypt and decrypt your data like below:
from cryptography.fernet import Fernet
from django.conf import settings
class CryptoService:
def __init__(self):
self.key_in_bytes_object = settings.ENCRYPTION_KEY.encode("utf-8")
self.crypto_engine = Fernet(self.key_in_bytes_object)
def encryption(self, data_to_encrypt):
bytes_data_to_encrypt = data_to_encrypt.encode("utf-8")
encrypted_data = self.crypto_engine.encrypt(bytes_data_to_encrypt)
return encrypted_data
def decryption(self, bytes_object_data_to_decrypt):
bytes_data_object = self.crypto_engine.decrypt(bytes_object_data_to_decrypt)
plain_text = bytes_data_object.decode("utf-8")
return plain_text
The Fernet class only takes the bytes object and returns the bytes object as well.
As you can see we are converting the encryption key to bytes object with ‘utf-8‘ in init method
encryption method: The encryption method takes plain text and return encrypted data(bytes object).
decryption method: The decryption method takes encrypted text(bytes object) and returns plain text.
Let’s see an example to text how our CryptoService working. Open you shell and continue wilt me..
>>> from home.service import CryptoService
>>> ser = CryptoService()
>>> plain_text = "hello world"
>>> encrypted_data_bytes_object = ser.encryption(plain_text)
>>> encrypted_data_bytes_object
b'gAAAAABkmxyEFzMujcCWrXSovK-LEvOKFh2K5YOV9ngbDZuE1rvyUdOrz9XfXxVPBpxIaKGZeeLgiK2Zqfuy7Xr1sFUnilmOlg=='
>>> plain_text = ser.decryption(encrypted_data_bytes_object)
>>> plain_text
'hello world'
As you can see, the encryption method returns the encrypted text as bytes object format.
b'gAAAAABkmxyEFzMujcCWrXSovK-LEvOKFh2K5YOV9ngbDZuE1rvyUdOrz9XfXxVPBpxIaKGZeeLgiK2Zqfuy7Xr1sFUnilmOlg=='
And decryption method takes the encrypted bytes object and return the plain text.
Conclusion –
You can use this package for any other python based project like FastAPI, Flask… and so on.
Stay tuned to learn more…
