Encryption is one of the main topic that comes into our mind when we talk about IT security. If you are unfamiliar with the filed Cryptography, there is a really simple article that I wrote few weeks ago about the basics that you need to know in cryptography. You can check that out from here.
In today’s article I’m going to talk about Python Encryption and Decryption.
In order to do python encryption and decryption we need to have a library which provides us the cryptographic functions. There are so many python libraries related to python encryption and decryption. PyCrypto, PyCryptodome, pyAesCrypt, Cryptography are some of the libraries available out there. In this article we are going to focus on the PyCryptodome library which is a is a fork of PyCrypto. So let’s get started.
PyCryptodome is a collection of low-level cryptographic algorithms written in pure Python. Only few parts which are extremely critical to performance are implemented as C extensions.
Easiest way to install libraries related to python is by using pip. pip is a package management system which we use to install and manage software packages related to python.
Open up your terminal (in Linux) / cmd (in windows) and run the following command.
pip install pycryptodome
Once you run the command it will automatically starts to download the wheel file of pycryptodome module and begin installing it. Once the installation completed you can import and use the library as your wish.
So in this article we are focusing on python Advanced Encryption Standard a.k.a AES encryption.
What is AES encryption?
AES is a symmetric block cipher established by the U.S. National Institute of Standards and Technology. If you are have no idea about AES encryption I recommend you to do some research and learn what it is and how it works before going further in this tutorial.
Let’s Write Some Code…
Since we don’t need each and every module inside pycryptodome library first of all we need import the modules that we need. We need only need to import the random module and AES module from pycryptodome.
from Crypto import Random #use to generate a random byte string of a length we decide from Crypto.Cipher import AES
And also we need to import base64 and hashlib modules. These are inbuilt modules in python. therefore you don’t have to install them manually.
import base64 import hashlib
Block sizes for AES encryption is 16 bytes or 128 bits. When AES encryption taking place it will divide our data into blocks of length 16. This is a fixed size. So what if your data is smaller than the blocksize ? That’s where padding comes into play. Now we need to create a padding function. And also we need to create a unpadding function so that we can remove the padding during our encryption process.
BS = 16 pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) unpad = lambda s : s[0:-s[-1]]
Given below is the rest of the code that we are going to talk about. I’ll explain them line by line.
class AESCipher: def __init__( self, key ): self.key = hashlib.sha256(key.encode('utf-8')).digest() def encrypt( self, raw ): raw = pad(raw) iv = Random.new().read( AES.block_size ) cipher = AES.new( self.key, AES.MODE_CBC, iv ) return base64.b64encode( iv + cipher.encrypt( raw.encode('utf8') ) ) def decrypt( self, enc ): enc = base64.b64decode(enc) iv = enc[:16] cipher = AES.new(self.key, AES.MODE_CBC, iv ) return unpad(cipher.decrypt( enc[16:] )) cipher = AESCipher('mysecretpassword') encrypted = cipher.encrypt('Secret Message A') decrypted = cipher.decrypt(encrypted) print(encrypted) print(decrypted)
At first we’ve created a class to include all the function related to encryption and decryption process.
Inside the class first function uses __init__ method. When we use this method it will run as soon as an object of a class is instantiated. (You will understand this at the end of this tute.) Moving on… This function will get the key and convert it to sha256 bit string. This key will be used during the encryption process. Why we are doing this? Because by converting it to hash value we can keep a fixed length of our key. So that we can insert any length of key as our encryption key. The length of the key will remain same.
Next we have the encryption function. Inside that function at first we are padding our data. Then we are generating a iv a.k.a initialization vector. (I’ll explain this in the latter part of this article) Next we are encrypting the data using the key and iv. Finally the encrypted data is returning as base64 encoded strings. During the encryption process the iv is stored in the first 16 bytes of data.
Next we have the decryption function. First we are decoding the base64 encoded data. Then identifying the iv by reading the first 16 bytes of data. Finally we can get the decrypted text out.
In line 19 we have created the object for the class AESCipher and assigned the key as ‘mysecretpassword’. Now we mentioned the object of the class AESCipher. Therefore __init__ method will run first before executing any other within the class AESCipher.
Last four lines of code will encrypt the string ‘Secret Message A’, decrypt it and print the outputs on our terminal.
What is IV (Initialization Vector)
This is a random bytes of strings with a fixed length that we used to randomize our encryption process. In simple terms, lets say that we have two text file with which are identical to each other. If encrypt these two files without using an IV the resulting cipher text of both text file will be the same. But if the encryption take place with the help of an IV even though the two files are identical to each other the resulting cipher text will be different to each other.
On next article i’m planing to teach you how to make a file encryption and decryption program using python. Thank you.