-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathencryption_utils.py
More file actions
125 lines (101 loc) · 4.11 KB
/
encryption_utils.py
File metadata and controls
125 lines (101 loc) · 4.11 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
import base64
class SymmetricEncryption:
"""Handles AES-256 symmetric encryption and decryption"""
@staticmethod
def generate_key():
"""Generate a random 256-bit (32 bytes) key"""
return get_random_bytes(32)
@staticmethod
def encrypt(message, key):
"""
Encrypt message using AES-256 in CBC mode
Returns: (encrypted_message, iv) both base64 encoded
"""
cipher = AES.new(key, AES.MODE_CBC)
# Convert message to bytes if it's a string
if isinstance(message, str):
message = message.encode('utf-8')
# Pad message to be multiple of 16 bytes
padded_message = pad(message, AES.block_size)
# Encrypt
ciphertext = cipher.encrypt(padded_message)
# Return base64 encoded ciphertext and IV
return base64.b64encode(ciphertext).decode('utf-8'), \
base64.b64encode(cipher.iv).decode('utf-8')
@staticmethod
def decrypt(encrypted_message, key, iv):
"""
Decrypt message using AES-256
"""
# Decode from base64
ciphertext = base64.b64decode(encrypted_message)
iv_bytes = base64.b64decode(iv)
# Create cipher
cipher = AES.new(key, AES.MODE_CBC, iv_bytes)
# Decrypt and unpad
decrypted_padded = cipher.decrypt(ciphertext)
decrypted = unpad(decrypted_padded, AES.block_size)
return decrypted.decode('utf-8')
class AsymmetricEncryption:
"""Handles RSA-2048 asymmetric encryption and decryption"""
@staticmethod
def generate_keys():
"""
Generate RSA-2048 key pair
Returns: (public_key, private_key) as PEM strings
"""
key = RSA.generate(2048)
private_key = key.export_key().decode('utf-8')
public_key = key.publickey().export_key().decode('utf-8')
return public_key, private_key
@staticmethod
def encrypt(message, public_key_pem):
"""
Encrypt message using RSA public key
Note: RSA can only encrypt small messages (up to 214 bytes for 2048-bit key)
"""
if isinstance(message, str):
message = message.encode('utf-8')
# Import public key
public_key = RSA.import_key(public_key_pem)
cipher = PKCS1_OAEP.new(public_key)
# Encrypt
ciphertext = cipher.encrypt(message)
# Return base64 encoded
return base64.b64encode(ciphertext).decode('utf-8')
@staticmethod
def decrypt(encrypted_message, private_key_pem):
"""
Decrypt message using RSA private key
"""
# Decode from base64
ciphertext = base64.b64decode(encrypted_message)
# Import private key
private_key = RSA.import_key(private_key_pem)
cipher = PKCS1_OAEP.new(private_key)
# Decrypt
decrypted = cipher.decrypt(ciphertext)
return decrypted.decode('utf-8')
def encrypt_file_content(file_content, encryption_type):
"""
Encrypt file content based on encryption type
Returns: encrypted data and keys
"""
if encryption_type == "Symmetric (AES-256)":
key = SymmetricEncryption.generate_key()
encrypted_msg, iv = SymmetricEncryption.encrypt(file_content, key)
key_str = base64.b64encode(key).decode('utf-8')
return encrypted_msg, key_str, iv
else:
public_key, private_key = AsymmetricEncryption.generate_keys()
# For large files with RSA, we'd typically use hybrid encryption
# For this demo, we'll handle small files only
if len(file_content) > 190: # RSA limit
raise ValueError("File too large for RSA encryption. Use symmetric encryption for large files.")
encrypted_msg = AsymmetricEncryption.encrypt(file_content, public_key)
return encrypted_msg, public_key, private_key