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:
To make life easy, we'll be using Classes, so here's how our class will look
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
# 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.
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
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
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:
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.
# 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.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.