MultiFernet Module in Python - GeeksforGeeks

20 Apr, 2021
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 modulesfrom cryptography.fernet import Fernet, MultiFernet # key generationkey1 = Fernet(Fernet.generate_key())key2 = Fernet(Fernet.generate_key()) # the MultiFernet takes a list of Fernet instancesf = MultiFernet([key1, key2]) # encryption and token generationtoken = f.encrypt(b"Welcome to GeeksForGeeks Python Module!") # display the ciphertextprint(token) # decryption of ciphertext to plaintextd = f.decrypt(token) #display the plaintext#decode() method converts byte to stringprint(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 modulesfrom cryptography.fernet import Fernet, MultiFernet # key generationkey1 = Fernet(Fernet.generate_key())key2 = Fernet(Fernet.generate_key()) # the MultiFernet takes a list of Fernet instancesf = MultiFernet([key1, key2]) # encryption and token generationtoken = f.encrypt(b"Welcome to GeeksForGeeks Python Module!") # display the ciphertextprint(token) # decryption of ciphertext to plaintextd = f.decrypt(token) #display the plaintextprint(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!
 
 
 
AshokJaiswal
cryptography
python-modules
python-utility
Python
cryptography
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Install PIP on Windows ?
Check if element exists in list in Python
How To Convert Python Dictionary To JSON?
How to drop one or multiple columns in Pandas Dataframe
Python Classes and Objects
Python | os.path.join() method
Python | Get unique values from a list
Create a directory in Python
Defaultdict in Python
Python | Pandas dataframe.groupby()