PTENES
MÓDULO 3.3

🔐 Cifrado y protección de secretos

Fernet + PBKDF2, UUID del hardware como clave, almacenamiento seguro en ~/.intelecto/.secrets y registro de auditoría inmutable.

6
Temas
75
Minutos
Avanzado
Nivel
Técnico
Tipo
1

🔑 Fernet — cifrado simétrico

Fernet es la solución más segura y sencilla para cifrar datos en reposo en Python. AES-128-CBC para cifrar, HMAC-SHA256 para autenticar: no puedes descifrar sin verificar también la integridad.

📌 Por qué Fernet es la elección correcta

Comparación con alternativas:

  • •Texto plano: clave visible en cualquier editor de texto — inaceptable
  • •Base64: no es cifrado, solo es encoding; los datos siguen expuestos
  • •AES puro: requiere gestionar IV, padding, modo de operación; propenso a errores
  • •Fernet: una línea de código, seguro semánticamente y autenticado: ideal

💡 Consejo práctico

Siempre usa from cryptography.fernet import Fernet. Nunca implementes tu propio cifrado: la biblioteca cryptography ha sido auditada por especialistas en seguridad.

2

🔗 PBKDF2 — derivación de claves

PBKDF2 transforma cualquier valor (como el UUID del hardware) en una clave criptográfica robusta. Las numerosas iteraciones hacen que la fuerza bruta sea computacionalmente inviable.

📌 Parámetros de PBKDF2

Configuraciones recomendadas para 2026:

  • •Hash: SHA-256 (el estándar más seguro disponible)
  • •Iteraciones: mínimo 600.000 para usar en hardware moderno
  • •Salt: 32 bytes aleatorios, almacenados junto con el hash
  • •Longitud: 32 bytes (256 bits) para usar como clave AES-256
  • •Biblioteca: hashlib.pbkdf2_hmac() — nativa de Python

💡 Consejo práctico

Usa más de 600.000 iteraciones (recomendación OWASP 2024). Parece mucho, pero tarda ~0.3 segundos en hardware moderno: un tiempo aceptable para desbloquear una clave.

3

💻 UUID del hardware como clave

O UUID del hardware es único por máquina e inmutable durante la vida útil del hardware. Usarlo como material para PBKDF2 crea un cifrado vinculado a una máquina específica.

📌 Cómo obtener el UUID del hardware

Método multiplataforma para obtener un UUID:

  • •Linux: cat /sys/class/dmi/id/product_uuid ou dmidecode -s system-uuid
  • •macOS: ioreg -rd1 -c IOPlatformExpertDevice | grep UUID
  • •Windows: wmic csproduct get UUID
  • •Fallback: generar un UUID determinístico basado en múltiples identificadores de hardware

💡 Consejo práctico

Prueba el UUID antes de cifrar datos importantes. Si el UUID cambia después de una actualización de BIOS o de cambiar el hardware, tus secretos quedarán inaccesibles sin una copia de seguridad de la clave original.

4

📁 Almacenamiento en ~/.intelecto/.secrets

El archivo ~/.intelecto/.secrets es donde viven las claves cifradas. Formato JSON simple, permisos restrictivos y ubicación oculta por convención.

📌 Estructura de .secrets

Formato del archivo de secretos:

  • •{"OPENROUTER_API_KEY": "gAAA...token_fernet..."}
  • •Cada clave: nombre del secreto
  • •Cada valor: token Fernet cifrado (comienza con gAAA)
  • •chmod 600: solo el propietario puede leer y escribir
  • •.gitignore: ~/.intelecto/ debe estar en el gitignore global

💡 Consejo práctico

Configura un gitignore global (~/.gitignore_global) que excluya ~/.intelecto/ de cualquier repositorio. Un accidente con git add . no debe exponer tus secretos.

5

📋 audit.log — Registro inmutable

O audit.log es la memoria forense de INTELECTO. Cada acción significativa se registra de forma append-only: el log solo crece, nunca se eliminan ni se modifican líneas.

📌 Formato del registro de auditoría

Cada línea del log es un JSON estructurado:

  • •{"ts": "2026-04-28T10:30:00Z", "user": "telegram:123", "action": "exec", "tool": "shell", "cmd": "ls -la", "result": "ok"}
  • •ts: timestamp ISO 8601 con zona horaria
  • •user: identificador del canal y del usuario
  • •action: tipo de acción (read, exec, deny, error)
  • •tool: qué tool se llamó (si corresponde)
  • •result: ok, denied, error

💡 Consejo práctico

Configura logrotate para el audit.log con la opción nocreate: conserva el archivo original. Comprime los logs antiguos, pero nunca los elimines. Son evidencia forense.

6

🔄 Rotación de claves

Las claves de API deben rotarse periódicamente. secrets.py admite varias claves con precedencia para permitir la rotación sin tiempo de inactividad.

📌 Proceso de rotación

Rotación sin interrupción del servicio:

  • •1. Generar una nueva clave Fernet
  • •2. Volver a cifrar los secretos con la nueva clave
  • •3. Configurar: current_key = nova, fallback_key = antiga
  • •4. Probar que el servicio funcione con la nueva clave
  • •5. Después de 24h de estabilidad: eliminar fallback_key
  • •6. Registrar la rotación en audit.log

💡 Consejo práctico

Programa la rotación automática de claves con cron: una vez por trimestre para uso personal, mensualmente para uso con datos sensibles. INTELECTO ya tiene listo el script rotate_keys.py.

✅ Resumen del Módulo 3.3

✓
Fernet — Cifrado simétrico — AES-128-CBC + HMAC-SHA256 en una API sencilla — la opción correcta para secrets
✓
PBKDF2 — Derivación de clave — más de 600k iteraciones, salt aleatorio, SHA-256 — derivación robusta de claves a partir del UUID del hardware
✓
UUID del hardware como clave — UUID único por máquina + PBKDF2 = cifrado que solo funciona en el hardware original
✓
Almacenamiento en ~/.intelecto/.secrets — JSON con tokens Fernet, chmod 600, ubicación oculta y fuera de cualquier repo git
✓
audit.log — Registro inmutable — JSON estructurado, append-only, con timestamp, usuario, acción y resultado — evidencia forense inmutable
✓
Rotación de claves — Multi-key con precedencia permite una rotación sin downtime en 6 etapas

Siguiente:

3.4 — IronClaw Zero-Trust