-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdecrypt_psychologger.py
More file actions
129 lines (104 loc) · 4.19 KB
/
decrypt_psychologger.py
File metadata and controls
129 lines (104 loc) · 4.19 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
128
129
#!/usr/bin/env python3
"""
Desencriptador de audios de PsychoLogger
Uso: python decrypt_psychologger.py audios_encrypted_2025-01-15.zip password
"""
import sys
import json
import zipfile
from io import BytesIO
from getpass import getpass
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
def hex_to_bytes(hex_string):
"""Convierte string hexadecimal a bytes"""
return bytes.fromhex(hex_string)
def derive_key(password, salt, iterations=120000, key_length=32):
"""
Deriva clave AES-256 desde contraseña usando PBKDF2
Parámetros:
- password: Contraseña en string
- salt: Salt en bytes (16 bytes)
- iterations: Iteraciones PBKDF2 (default: 120,000)
- key_length: Longitud de clave en bytes (32 = 256 bits)
"""
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=key_length,
salt=salt,
iterations=iterations
)
return kdf.derive(password.encode('utf-8'))
def decrypt_zip(encrypted_zip_path, password, output_dir="decrypted_audios"):
"""
Desencripta un ZIP de audios cifrado
PROCESO:
1. Abrir ZIP externo
2. Leer metadata.json → extraer salt, iv, iterations
3. Leer data.enc → bytes cifrados
4. Derivar clave AES desde password + salt
5. Desencriptar data.enc con AES-256-GCM
6. Extraer ZIP interno con los audios
"""
print(f"🔓 Desencriptando: {encrypted_zip_path}")
# 1. Abrir ZIP externo
with zipfile.ZipFile(encrypted_zip_path, 'r') as outer_zip:
# 2. Leer metadata.json
with outer_zip.open('metadata.json') as f:
metadata = json.load(f)
print(f"📄 Metadata:")
print(f" - Algoritmo: {metadata['algorithm']}")
print(f" - Iteraciones: {metadata['iterations']}")
print(f" - Timestamp: {metadata.get('timestamp', 'N/A')}")
# Extraer salt e IV
salt = hex_to_bytes(metadata['salt'])
iv = hex_to_bytes(metadata['iv'])
iterations = metadata['iterations']
print(f" - Salt: {len(salt)} bytes")
print(f" - IV: {len(iv)} bytes")
# 3. Leer data.enc (bytes cifrados)
with outer_zip.open('data.enc') as f:
encrypted_data = f.read()
print(f"📦 Datos cifrados: {len(encrypted_data)} bytes")
# 4. Derivar clave AES desde contraseña
print(f"🔑 Derivando clave AES-256 con PBKDF2 ({iterations} iteraciones)...")
key = derive_key(password, salt, iterations)
# 5. Desencriptar con AES-256-GCM
print(f"🔐 Desencriptando con AES-256-GCM...")
try:
aesgcm = AESGCM(key)
decrypted_zip_bytes = aesgcm.decrypt(iv, encrypted_data, None)
except Exception as e:
print(f"❌ ERROR: Contraseña incorrecta o datos corruptos")
print(f" Detalle: {e}")
return False
print(f"✅ Desencriptado exitoso: {len(decrypted_zip_bytes)} bytes")
# 6. Extraer ZIP interno con los audios
print(f"📂 Extrayendo audios a: {output_dir}/")
import os
os.makedirs(output_dir, exist_ok=True)
with zipfile.ZipFile(BytesIO(decrypted_zip_bytes)) as inner_zip:
audio_files = [f for f in inner_zip.namelist() if f.startswith('audios/')]
print(f"🎵 Audios encontrados: {len(audio_files)}")
for audio_file in audio_files:
filename = os.path.basename(audio_file)
output_path = os.path.join(output_dir, filename)
with inner_zip.open(audio_file) as source:
with open(output_path, 'wb') as target:
target.write(source.read())
print(f" ✓ {filename}")
print(f"\n✅ ¡Desencriptado completado!")
return True
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Uso: python3 decrypt_psychologger.py <archivo.zip> [password]")
print("Si no se proporciona password, se pedirá de forma segura")
sys.exit(1)
zip_path = sys.argv[1]
# Pedir contraseña de forma segura (no visible en terminal)
if len(sys.argv) >= 3:
password = sys.argv[2]
else:
password = getpass("🔒 Contraseña: ")
decrypt_zip(zip_path, password)