Open In App

MultiFernet Module in Python

Improve
Improve
Like Article
Like
Save
Share
Report

Cryptography is the process or technique of converting plaintext into ciphertext to protect information from the hackers during transmission from one computer to another. Python cryptography module allows the conversion of plaintext or message (in bytes) into ciphertext using the fernet module. The fernet module consists of inbuilt methods encrypt(), decrypt() and generate_key() to encrypt, decrypt and generate keys for encryption. The text message encrypted using fernet cannot be manipulated or read without the key. The MultiFernet class implements key rotation for Fernet. The MultiFernet has an inbuilt method rotate() which can be further used to retire an old key that has been exposed. 
 

Methods used:

generate_key(): This method generates a new fernet key. The key must be kept safe as it is the most important component to decrypt the ciphertext. If the key is lost then the user can no longer decrypt the message. Also if an intruder or hacker gets access to the key they can not only read the data but also forge the data.

encrypt(data): It encrypts data passed as a parameter to the method. The outcome of this encryption is known as a “Fernet token” which is basically the ciphertext. The encrypted token also contains the current timestamp when it was generated in plaintext. The encrypt method throws an exception if the data is not in bytes.

Syntax: encrypt(data)

Parameter: 

  • data (bytes) – The plaintext to be encrypted.

Returns: A ciphertext that cannot be read or altered without the key. It is URL-safe base64-encoded and is referred to as Fernet token.

decrypt(token, ttl = None): This method decrypts the Fernet token passed as a parameter to the method. On successful decryption the original plaintext is obtained as a result, otherwise, an exception is thrown.

Syntax: decrypt(token, ttl = None)

Parameters: 

  • token (bytes) – The Fernet token (ciphertext) is passed for decryption.
  • ttl (int) – Optionally, one may provide an integer as the second parameter in the decrypt method. The ttl denotes the time about how long a token is valid. If the token is older than ttl seconds (from the time it was originally created) an exception is thrown. If ttl is not passed as a parameter, then age of the token is not considered. If the token is somehow invalid, an exception is thrown.

Returns: Returns the original plaintext.

rotate(token): This method rotates a token by re-encrypting with the MultiFernet instance’s primary key. However, re-encryption preserves the timestamp originally saved with the token. 

Syntax: rotate(token)

Parameter: 

  • token (bytes): The token to be rotated for re-encryption

Returns: If the token has successfully been rotated then the rotated token is returned. If rotation fails then it throws an exception.

Install cryptography package:

pip install cryptography

First Approach 
MultiFernet performs encryption using the first key in the list provided. MultiFernet decrypts tokens with each key in turn. If the correct key is not found in the list provided, a cryptography.fernet.InvalidToken exception is thrown. In the code snippet below, keys are generated and appended to the list. The MultiFernet takes the first key and stores in the f variable. This key is used to encrypt the plaintext into ciphertext. On the other hand, during decryption, MultiFernet tries all the keys in the list to decrypt the ciphertext. 
 

Python3




# import Fernet and MultiFernet modules
from cryptography.fernet import Fernet, MultiFernet
 
# key generation
key1 = Fernet(Fernet.generate_key())
key2 = Fernet(Fernet.generate_key())
 
# the MultiFernet takes a list of Fernet instances
f = MultiFernet([key1, key2])
 
# encryption and token generation
token = f.encrypt(b"Welcome to GeeksForGeeks Python Module!")
 
# display the ciphertext
print(token)
 
# decryption of ciphertext to plaintext
d = f.decrypt(token)
 
#display the plaintext
#decode() method converts byte to string
print(d.decode())


 

 

Output:

 

b’gAAAAABfYfRrB3f0RQl108YFuGyFHZ2lIQBKpFkuEqJ0EgLi6TNPR9vhElTmyuo5EfBivBwEBfSkOQJPEtIqOBBKZH8iElFn3ON5eg5d_JA1G9oARG7RKiqiQiOP8R22U4pIxnO1banH’

Welcome to GeeksForGeeks Python Module!

 

Second Approach 
The second approach demonstrates key rotation. Key rotation makes it easy to replace old or exposed keys. The new key can be added at the front of the already existing key list to start encrypting new messages, and the old keys are removed as they are no longer needed. Token rotation offered by MultiFernet.rotate() limits the damage in the event of an undetected event and to increase the difficulty or frequency of attacks. For example, if an employee having access to the company’s fernet keys leaves, the company will want to generate a new fernet key, rotate all of the tokens deployed currently using the new key, and remove the old fernet keys to which the employee had access. This can be easily achieved by MultiFernet. 
 

 

Python3




# import Fernet and MultiFernet modules
from cryptography.fernet import Fernet, MultiFernet
 
# key generation
key1 = Fernet(Fernet.generate_key())
key2 = Fernet(Fernet.generate_key())
 
# the MultiFernet takes a list of Fernet instances
f = MultiFernet([key1, key2])
 
# encryption and token generation
token = f.encrypt(b"Welcome to GeeksForGeeks Python Module!")
 
# display the ciphertext
print(token)
 
# decryption of ciphertext to plaintext
d = f.decrypt(token)
 
#display the plaintext
print(d.decode())
 
print('Key rotation')
key3 = Fernet(Fernet.generate_key())
f2 = MultiFernet([key3, key1, key2])
rotated = f2.rotate(token)
d2 = f2.decrypt(rotated)
print(d2.decode())


 

 

Output:

 

b’gAAAAABfYfUe1Zh3JAa33k_RBRgkXgh-40jS6iqjXEq5Tc6jCeds-QY_nmlhzjkVBdZzeoExKj-YJsefBkgVSjUH1CVNG4080cwa3ZBHA9Aftx5upXzNQnaZ5fgeJacPNY0jcm4PMZSs’

Welcome to GeeksForGeeks Python Module!

Key rotation

Welcome to GeeksForGeeks Python Module!

 

 

 



Last Updated : 20 Apr, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads