-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathencryption.py
More file actions
127 lines (101 loc) · 4.09 KB
/
Copy pathencryption.py
File metadata and controls
127 lines (101 loc) · 4.09 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
126
127
"""
Encryptum Clone - Core Encryption Module
Handles AES-256 encryption/decryption with PBKDF2 key derivation
"""
import os
import hashlib
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import base64
import logging
class EncryptumCrypto:
"""Core encryption handler for Encryptum clone"""
def __init__(self, iterations=100000):
self.iterations = iterations
self.logger = logging.getLogger(__name__)
def generate_key_from_password(self, password: str, salt: bytes = None) -> tuple:
"""
Generate encryption key from password using PBKDF2
Args:
password: User password
salt: Salt bytes (generated if None)
Returns:
tuple: (key, salt)
"""
if salt is None:
salt = os.urandom(16)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=self.iterations,
)
key = base64.urlsafe_b64encode(kdf.derive(password.encode()))
return key, salt
def encrypt_file(self, file_path: str, password: str) -> dict:
"""
Encrypt file and return encrypted data + metadata
Args:
file_path: Path to file to encrypt
password: Encryption password
Returns:
dict: Encryption result with metadata
"""
try:
# Validate file exists
if not os.path.exists(file_path):
raise FileNotFoundError(f"File not found: {file_path}")
# Generate key and salt
key, salt = self.generate_key_from_password(password)
fernet = Fernet(key)
# Read and encrypt file
with open(file_path, 'rb') as file:
file_data = file.read()
if len(file_data) == 0:
raise ValueError("Cannot encrypt empty file")
encrypted_data = fernet.encrypt(file_data)
# Calculate hash for verification
file_hash = hashlib.sha256(file_data).hexdigest()
self.logger.info(f"File encrypted successfully: {os.path.basename(file_path)}")
return {
'encrypted_data': encrypted_data,
'salt': salt,
'original_hash': file_hash,
'original_name': os.path.basename(file_path),
'original_size': len(file_data),
'encrypted_size': len(encrypted_data)
}
except Exception as e:
self.logger.error(f"Encryption failed: {str(e)}")
raise Exception(f"Encryption failed: {str(e)}")
def decrypt_file(self, encrypted_data: bytes, password: str, salt: bytes) -> bytes:
"""
Decrypt file data
Args:
encrypted_data: Encrypted file bytes
password: Decryption password
salt: Salt used for key derivation
Returns:
bytes: Decrypted file data
"""
try:
key, _ = self.generate_key_from_password(password, salt)
fernet = Fernet(key)
decrypted_data = fernet.decrypt(encrypted_data)
self.logger.info("File decrypted successfully")
return decrypted_data
except Exception as e:
self.logger.error(f"Decryption failed: {str(e)}")
raise Exception(f"Decryption failed: {str(e)}")
def verify_file_integrity(self, decrypted_data: bytes, original_hash: str) -> bool:
"""
Verify file integrity using hash
Args:
decrypted_data: Decrypted file data
original_hash: Original file hash
Returns:
bool: True if integrity verified
"""
current_hash = hashlib.sha256(decrypted_data).hexdigest()
return current_hash == original_hash