How To Encrypt/Decrypt Files - Python

Cryptography is the study of application and techniques that hide the real meaning of information by transmitting it into a non-human readable format and vice versa.
For cryptography to take place two process needs to get involved namely:

  • Encryption
  • Decryption

  • Encryption: is the process of transforming information into a non-human readable form. while
  • Decryption: is the process of transforming information into a human readable form.

A key(secret key) is needed for encryption and decryption to take place. this key is unique.
In symmetric encryption scheme the same key is needed for both encryption and decryption while in asymmetric encryption scheme two different keys are required, one for encryption (public key) and the other for decryption (private key), these two keys are mathematically associated.
In this tutorial we will be using the Cryptography Library which was built on top of AES algorithm

First we need to install the library using:

  


pip3 install cryptography

We'll be using the Fernet class, so let's import this line:


  


from cryptography import fernet.Fernet

To make life easy, we'll be using Classes, so here's how our class will look


  


class Encrypter:

    def __init__(self, key_file, target_file):
        self.key_file = key_file
        self.target_file = target_file

As you can see, in our class we defined a constructor, so whenever we want to create an object of this class, we need to pass two things, first is the key_file which is representing a file which we'll write or read the key from, the second one is the target_file which is the file that needs to be encrypted or decrypted.
Next we'll write a function in our class that'll generate the key for us and write into the key_file


  


# Generate a new key and write it
# to the key file
def generate_new_key(self):

    key = Fernet.generate_key()

    with open(self.key_file, "wb") as file:
        file.write(key)

Next we'll create another function in our class for loading the key from the key_file.


  


# Reading the key from the file
def load_key(self):

    return open(self.key_file, "rb").read()

Next we'll create another two functions in our class, one for encrypting the file, and the other for decrypting it!.


Encrypting The File


  


# Function to encrypt the file
def encrypt_file(self):

    key = self.load_key()
    # create a new Fernet object with the key.
    f = Fernet(key)
    content = b""

    # read the file and store it in content varaible
    with open(self.target_file, "rb") as file:
        content = file.read()

    # encrypt the file and store the encrypted text
    encrypted = f.encrypt(content)

    # open the file and override the plantext content
    # with the encrypted one
    with open(self.target_file, "wb") as file:
        file.write(encrypted)

Decrypting The File


  


# Function for decrypting the file
def decrypt_file(self):

    key = self.load_key()
    # create a new fernet object with the key
    f = Fernet(key)
    content = b""

    #read the file content and store it in the content variable
    with open(self.target_file, "rb") as file:
        content = file.read()

    # decrypt the file with the decrypt() method of Fernet
    decrypted = f.decrypt(content)

    # write the decrypted content into the target_file
    with open(self.target_file, "wb") as file:
        file.write(decrypted)

The encrypt() and decrypt() method of Fernet class are use for encryption and decryption respectively.

Full source code:


  


from cryptography.fernet import Fernet

class Encrypter:

    def __init__(self, key_file, target_file):
        self.key_file = key_file
        self.target_file = target_file


    # Generate a new key and write it
    # to the key file
    def generate_new_key(self):

        key = Fernet.generate_key()

        with open(self.key_file, "wb") as file:
            file.write(key)


    # Reading the key from the file
    def load_key(self):

        return open(self.key_file, "rb").read()


    # Function to encrypt the file
    def encrypt_file(self):

        key = self.load_key()
        f = Fernet(key)
        content = b""

        # read the file and store it in content varaible
        with open(self.target_file, "rb") as file:
            content = file.read()

        # encrypt the file and store the encrypted text
        encrypted = f.encrypt(content)

        # open the file and override the plantext content
        # with the encrypted one
        with open(self.target_file, "wb") as file:
            file.write(encrypted)


    # Function for decrypting the file
    def decrypt_file(self):

        key = self.load_key()
        # create a new fernet object with the key
        f = Fernet(key)
        content = b""

        #read the file content and store it in the content variable
        with open(self.target_file, "rb") as file:
            content = file.read()

        # decrypt the file with the decrypt() method of Fernet
        decrypted = f.decrypt(content)

        # write the decrypted content into the target_file
        with open(self.target_file, "wb") as file:
            file.write(decrypted)


Let's see an example of encrypting a file.




Please try this example with a non useful or junk file, because you may lose sensitive data if you accidentally deleted the key.

  


enc = Encrypter('key.key', 'tmp.txt')
# generate a new key for encryption and decryption
enc.generate_new_key()
enc.encrypt_file()

Initially this is what I've in my tmp.txt file:

  


23,1,HipHop
25,1,HipHop
26,1,Jazz
29,1,Jazz
30,1,Jazz
31,1,Classical
33,1,Classical
37,1,Classical
20,0,Dance
21,0,Dance
25,0,Dance
26,0,Acoustic
27,0,Acoustic
30,0,Acoustic
31,0,Classical
34,0,Classical
35,0,Classical

And after running the program this is what I've now:

  


gAAAAABifzIEN9NKZGvGuo-PA8-sRrl_K8K4UGm-n1yBnwQLGSZf71uiJSHCv_djKit9HZcFL4QCXhgY0GJhDtLJ7Gv3nJq0Y77HELqK0tOqMY_E_7T5eGkhtVg082x5LDMlvZG3es3w9i3xvS7sesJ9I8vAPkAPSbj_9hwbJCo65GVkBHc6jEYQsgJ9KIhpWLEjhl9TON0uKeCxhPpj1nUuFx1YjPAaqkQ9e3fhrzMHwLHuf-DAoKVi3m0-HPTPMOGuRfpmBbw4x0AWtqKssrDsVi9XO101si5EljPjwN_tlS9d_JeU09mzlACw9ybmsjzzvcy9iteNJ3CJOxinBLCkC_ZmHPAgNuLzCGn8h9h0dULliXsaCmc5TTAcCyO7UqKINm3pguPy0q7hXPCf6Ct7Q6ImzGhsjg==

You can change the tmp.txt with the name and path of the file you wish to test this with.
Now let's try to decrypt the file

  


enc = Encrypter('key.key', 'tmp.txt')
enc.decrypt_file()

And now after decrypting the file using the same key, this is what I've

  


23,1,HipHop
25,1,HipHop
26,1,Jazz
29,1,Jazz
30,1,Jazz
31,1,Classical
33,1,Classical
37,1,Classical
20,0,Dance
21,0,Dance
25,0,Dance
26,0,Acoustic
27,0,Acoustic
30,0,Acoustic
31,0,Classical
34,0,Classical
35,0,Classical

As you can see from the example above, we don't need to call the generate_new_key() method again since we already have our key, and be mindful that we must use the same key we used in encrypting the file while decrypting it.