Documento Técnico de Seguridad SeraVault

Arquitectura Técnica & Implementación Criptográfica Post-Cuántica

Versión: 1.0 Fecha: Noviembre 2025 Estado: Producción

1. Resumen

SeraVault es una plataforma de almacenamiento de archivos y mensajería cifrada de extremo a extremo de conocimiento cero, diseñada para resistir ataques de computadoras tanto clásicas como cuánticas. El sistema emplea ML-KEM-768 (NIST FIPS 203), un mecanismo de encapsulación de claves basado en retículas estandarizado por el NIST para criptografía post-cuántica, combinado con AES-256-GCM para cifrado simétrico.

Este documento técnico proporciona una descripción técnica completa de la arquitectura criptográfica de SeraVault, modelo de seguridad e implementación. Detallamos nuestro diseño de conocimiento cero, protocolos de gestión de claves y primitivas criptográficas post-cuánticas.

Nota: Este es un documento vivo. A medida que los estándares criptográficos evolucionen y la investigación de seguridad progrese, actualizaremos nuestra implementación y esta documentación en consecuencia. La versión actual refleja el sistema de producción a noviembre de 2025.

2. Modelo de Amenaza

2.1 Capacidades del Adversario

SeraVault está diseñado para proteger contra los siguientes adversarios:

2.1.1 Compromiso del Servidor

Asumimos que la infraestructura del servidor puede estar completamente comprometida. Un atacante que obtenga acceso completo a nuestros servidores no debería poder descifrar archivos o mensajes de usuarios. Esto se logra mediante cifrado del lado del cliente donde las claves de cifrado nunca llegan al servidor en texto plano.

2.1.2 Adversario de Red

Asumimos que un adversario puede interceptar, modificar o inyectar tráfico de red entre clientes y servidores. TLS proporciona seguridad a nivel de transporte, pero nuestro cifrado a nivel de aplicación garantiza que incluso el compromiso de TLS no exponga datos en texto plano.

2.1.3 Adversario Cuántico

Anticipamos futuros adversarios con acceso a computadoras cuánticas criptográficamente relevantes (CRQC). Los criptosistemas de clave pública tradicionales como RSA y la criptografía de curva elíptica son vulnerables al algoritmo de Shor. SeraVault usa ML-KEM-768, que se basa en la dificultad de problemas de retículas que se cree son resistentes a ataques cuánticos.

2.1.4 Adversario Estatal

Diseñamos contra actores estatales con recursos computacionales significativos, la capacidad de obligar a los proveedores de servicios y capacidades de "Cosechar Ahora, Descifrar Después" donde los datos cifrados se almacenan para un descifrado futuro cuando las computadoras cuánticas estén disponibles.

2.2 Supuestos de Confianza

2.3 Fuera del Alcance

Las siguientes amenazas están explícitamente fuera del alcance:

3. Arquitectura del Sistema

3.1 Diseño de Conocimiento Cero

SeraVault implementa una verdadera arquitectura de conocimiento cero donde el servidor no tiene acceso a:

Todas las operaciones de cifrado y descifrado ocurren del lado del cliente en el navegador o aplicación del usuario. El servidor almacena solo datos cifrados y actúa como una capa de almacenamiento y sincronización pasiva.

3.2 Descripción General de Componentes

3.2.1 Aplicación Cliente

3.2.2 Backend en la Nube

3.3 Flujo de Datos

Flujo de Carga de Archivo

  1. El usuario selecciona archivo en el navegador
  2. El cliente genera clave simétrica aleatoria de 256 bits (Clave de Archivo)
  3. El cliente cifra el contenido del archivo con AES-256-GCM usando Clave de Archivo
  4. El cliente cifra metadatos del archivo (nombre, tamaño, tipo) con el Secreto Compartido del usuario
  5. El cliente encapsula la Clave de Archivo para la clave pública del usuario usando ML-KEM-768
  6. El cliente carga el blob cifrado al almacenamiento en la nube
  7. El cliente escribe metadatos cifrados y clave encapsulada en la base de datos backend

Flujo de Descarga de Archivo

  1. El cliente recupera metadatos cifrados de la base de datos backend
  2. El cliente descifra metadatos usando el Secreto Compartido del usuario
  3. El cliente desencapsula la Clave de Archivo usando ML-KEM-768 con la clave privada del usuario
  4. El cliente descarga el blob cifrado del almacenamiento en la nube
  5. El cliente descifra el contenido del archivo con AES-256-GCM usando la Clave de Archivo
  6. El cliente presenta el archivo en texto plano al usuario

4. Primitivas Criptográficas

4.1 ML-KEM-768 (NIST FIPS 203)

Mecanismo de Encapsulación de Claves Basado en Retículas Modulares es nuestra primitiva criptográfica post-cuántica principal, estandarizada por el NIST en agosto de 2024 como FIPS 203.

Parámetros

Parámetro Valor
Nivel de Seguridad NIST Nivel 3 (equivalente a AES-192)
Tamaño Clave Pública 1,184 bytes
Tamaño Clave Privada 2,400 bytes
Tamaño Texto Cifrado 1,088 bytes
Tamaño Secreto Compartido 32 bytes

¿Por qué ML-KEM-768?

4.2 AES-256-GCM

Advanced Encryption Standard con claves de 256 bits en modo Galois/Counter proporciona cifrado autenticado para contenidos de archivos.

Propiedades

4.3 ChaCha20-Poly1305

ChaCha20-Poly1305 es un algoritmo de cifrado autenticado de alta velocidad utilizado para proteger material de clave sensible (como tu clave privada) en reposo.

4.4 Argon2id

Argon2id para derivar claves de cifrado a partir de frases de contraseña de usuario. Ganador del Password Hashing Competition (2015).

Por qué Argon2id: Argon2id requiere mucha memoria, haciendo que los ataques GPU y ASIC sean costosos. Combina enfoques independientes de datos (Argon2i) y dependientes de datos (Argon2d) para resistencia a canales laterales y máxima protección contra intentos de descifrado paralelos.

5. Protocolo de Cifrado de Archivos

5.1 Generación de Claves

Cuando un usuario crea su cuenta por primera vez y genera sus claves de cifrado:

// Generar par de claves ML-KEM-768 (clavePublica, clavePrivada) = ML-KEM-768.KeyGen() // Derivar clave de cifrado desde frase de contraseña sal = CSPRNG(32 bytes) claveCifrado = Argon2id(fraseContraseña, sal, t=3, m=64MiB, p=4, 32 bytes) // Cifrar clave privada con clave derivada de frase de contraseña nonce = CSPRNG(12 bytes) clavePrivadaCifrada = ChaCha20-Poly1305.Encrypt(claveCifrado, nonce, clavePrivada) // Almacenar clave privada cifrada en base de datos backend // Clave pública almacenada en base de datos backend (texto plano, es pública)

5.2 Cifrado de Archivo

Para cada archivo cargado:

// 1. Generar clave de cifrado de archivo aleatoria claveArchivo = CSPRNG(32 bytes) // 2. Cifrar contenido del archivo nonce = CSPRNG(12 bytes) contenidoCifrado = AES-256-GCM.Encrypt(claveArchivo, nonce, contenidoArchivo) // El resultado incluye etiqueta de autenticación de 16 bytes // 3. Encapsular clave de archivo para propietario (textoCifrado, secretoCompartido) = ML-KEM-768.Encapsulate(clavePublicaPropietario) // Secreto compartido se usa para cifrar la clave de archivo nonceClave = CSPRNG(12 bytes) claveArchivoCifrada = AES-256-GCM.Encrypt(secretoCompartido, nonceClave, claveArchivo) // 4. Cifrar metadatos metadatos = {nombre, tamaño, tipo, fechaCarga} nonceMetadatos = CSPRNG(12 bytes) metadatosCifrados = AES-256-GCM.Encrypt(secretoCompartidoUsuario, nonceMetadatos, metadatos)

5.3 Descifrado de Archivo

// 1. Descifrar clave privada usando frase de contraseña claveCifrado = Argon2id(fraseContraseña, sal, t=3, m=64MiB, p=4, 32 bytes) clavePrivada = ChaCha20-Poly1305.Decrypt(claveCifrado, nonce, clavePrivadaCifrada) // 2. Desencapsular para recuperar secreto compartido secretoCompartido = ML-KEM-768.Decapsulate(clavePrivada, textoCifrado) // 3. Descifrar clave de archivo claveArchivo = AES-256-GCM.Decrypt(secretoCompartido, nonceClave, claveArchivoCifrada) // 4. Descifrar contenido de archivo contenidoArchivo = AES-256-GCM.Decrypt(claveArchivo, nonce, contenidoCifrado) // 5. Descifrar metadatos metadatos = AES-256-GCM.Decrypt(secretoCompartidoUsuario, nonceMetadatos, metadatosCifrados)

5.4 Cifrado de Metadatos

A diferencia de muchos sistemas de almacenamiento cifrado, SeraVault cifra los metadatos de archivo incluyendo:

Esto evita que el servidor construya un perfil de los patrones de actividad del usuario basado en nombres o tipos de archivos.

Visibilidad de Metadatos: Aunque el contenido y los nombres están cifrados, el servidor todavía conoce:
  • Tamaños de blobs cifrados (tamaños aproximados de archivos)
  • Marcas de tiempo de carga/modificación
  • Número de archivos por usuario
  • Relaciones de compartir (usuario A compartió algo con usuario B)
Esto es inherente a cualquier sistema de almacenamiento en la nube y no puede eliminarse completamente sin usar técnicas como ORAM (Oblivious RAM), que impactarían severamente el rendimiento.

6. Gestión de Claves

6.1 Jerarquía de Claves de Usuario

Cada usuario tiene múltiples claves que sirven diferentes propósitos:

Tipo de Clave Propósito Almacenamiento
Clave Pública ML-KEM-768 Encapsulación de clave de archivo (otros cifran para ti) Base de datos backend (texto plano)
Clave Privada ML-KEM-768 Desencapsulación de clave de archivo Base de datos backend (cifrada con clave derivada de frase de contraseña)
Secreto Compartido Cifrado de metadatos Derivado del par de claves ML-KEM-768
Clave Derivada de Frase de Contraseña Cifra la clave privada Derivada bajo demanda, nunca almacenada

6.2 Ubicaciones de Almacenamiento de Claves

Importante: SeraVault soporta múltiples métodos de autenticación simultáneamente. Los usuarios pueden habilitar autenticación por frase de contraseña, por clave de hardware y biométrica al mismo tiempo. Cada método almacena una copia cifrada independientemente de la clave privada en diferentes ubicaciones, proporcionando redundancia y flexibilidad.

6.2.1 Autenticación por Frase de Contraseña

El método de autenticación principal donde la clave privada está cifrada con una clave derivada de frase de contraseña y almacenada en la base de datos backend:

6.2.2 Autenticación por Clave de Hardware

Los usuarios pueden habilitar autenticación por clave de hardware además o en lugar de autenticación por frase de contraseña. Las claves privadas están protegidas por una clave de seguridad de hardware (YubiKey, Titan Key) usando FIDO2/WebAuthn:

Compromiso Clave de Hardware: Si usa claves de hardware sin autenticación por frase de contraseña, perder la clave de hardware significa perder acceso a sus datos cifrados a menos que tenga una clave de respaldo o archivo de clave exportado. La clave privada cifrada en IndexedDB no puede descifrarse sin la clave de hardware física presente.

6.2.3 Autenticación Biométrica

Los usuarios pueden habilitar autenticación biométrica (huella digital, Face ID) para acceso conveniente en dispositivos móviles:

6.2.4 Respaldo de Archivo de Clave

Los usuarios pueden exportar su clave privada cifrada con una frase de contraseña separada:

6.3 Rotación de Claves

SeraVault soporta rotación de claves para mantener el secreto hacia adelante:

Proceso de Rotación de Claves

  1. El usuario genera un nuevo par de claves ML-KEM-768
  2. Para cada archivo propiedad del usuario:
    • Descifrar clave de archivo usando clave privada antigua
    • Re-encapsular clave de archivo usando clave pública nueva
    • Actualizar base de datos backend con nueva clave encapsulada
  3. Para cada archivo compartido:
    • Notificar a socios de compartir del cambio de clave
    • Re-encapsular claves compartidas con clave pública nueva
  4. Clave privada antigua borrada de forma segura
  5. Clave pública nueva publicada
Consideración de Rendimiento: La rotación de claves para usuarios con miles de archivos puede consumir tiempo. La operación se realiza incrementalmente en segundo plano.

7. Compartir Archivos Seguro

7.1 Modelo de Compartir

SeraVault implementa encapsulación de clave por destinatario para compartir archivos:

// El propietario del archivo comparte archivo con destinatario // 1. El propietario recupera clave pública del destinatario desde base de datos backend clavePublicaDestinatario = Backend.getPublicKey(idUsuarioDestinatario) // 2. El propietario descifra clave de archivo para sí mismo secretoCompartidoPropietario = ML-KEM-768.Decapsulate(clavePrivadaPropietario, textoCifradoPropietario) claveArchivo = AES-256-GCM.Decrypt(secretoCompartidoPropietario, nonceClave, claveArchivoCifrada) // 3. El propietario encapsula clave de archivo para destinatario (textoCifradoDestinatario, secretoCompartidoDestinatario) = ML-KEM-768.Encapsulate(clavePublicaDestinatario) nonceClaveDestinatario = CSPRNG(12 bytes) claveArchivoCifradaDestinatario = AES-256-GCM.Encrypt(secretoCompartidoDestinatario, nonceClaveDestinatario, claveArchivo) // 4. Almacenar clave encapsulada del destinatario en base de datos backend Backend.grantAccess(idArchivo, idUsuarioDestinatario, textoCifradoDestinatario, claveArchivoCifradaDestinatario)

7.2 Propiedades de Compartir

7.3 Modelo de Permisos

Permiso Descripción
Propietario Control total: leer, modificar, eliminar, compartir, revocar
Ver Puede descifrar y ver archivo, no puede modificar o compartir

Actualmente, SeraVault implementa un modelo simple de permisos propietario/ver. Los usuarios compartidos pueden ver archivos pero no pueden modificarlos o compartirlos con otros.

7.4 Compartir de Grupo

Para compartir con múltiples usuarios, el propietario puede crear un "compartir de grupo":

Costo de Almacenamiento: Cada archivo compartido requiere almacenar una clave encapsulada por destinatario (~1 KB). Para compartir a gran escala, esto es insignificante comparado con el contenido del archivo mismo. Solo se consume la cuota de almacenamiento del propietario del archivo, sin importar con cuántas personas se comparte.

8. Métodos de Autenticación

8.1 Autenticación Multi-Factor

SeraVault separa la autenticación de cuenta del acceso a claves de cifrado:

8.2 Autenticación Basada en Frase de Contraseña

El método de autenticación predeterminado:

8.3 Autenticación Biométrica

Usa WebAuthn con autenticadores de plataforma:

8.4 Autenticación por Clave de Hardware (YubiKey)

Usa FIDO2/CTAP2 para autenticación respaldada por hardware:

8.5 Passkey (Autenticador de Plataforma)

Autenticación moderna sin contraseña usando WebAuthn:

9. Mensajería Cifrada

9.1 Arquitectura de Chat

SeraVault incluye mensajería cifrada de extremo a extremo usando las mismas primitivas criptográficas que el cifrado de archivos:

9.2 Intercambio de Clave de Conversación

// Crear una conversación // 1. Iniciador genera clave de conversación aleatoria claveConversacion = CSPRNG(32 bytes) // 2. Para cada participante (incluyendo iniciador): (textoCifrado_i, secretoCompartido_i) = ML-KEM-768.Encapsulate(clavePublica_participante_i) nonce_i = CSPRNG(12 bytes) claveConversacionCifrada_i = AES-256-GCM.Encrypt(secretoCompartido_i, nonce_i, claveConversacion) // 3. Almacenar claves de conversación cifradas en base de datos backend // Cada participante puede descifrar usando su clave privada

9.3 Cifrado de Mensaje

// Enviar un mensaje // 1. Remitente descifra clave de conversación secretoCompartido = ML-KEM-768.Decapsulate(clavePrivadaRemitente, textoCifradoRemitente) claveConversacion = AES-256-GCM.Decrypt(secretoCompartido, nonce, claveConversacionCifrada) // 2. Cifrar mensaje nonceMensaje = CSPRNG(12 bytes) mensajeCifrado = AES-256-GCM.Encrypt(claveConversacion, nonceMensaje, contenidoMensaje) // 3. Cargar a base de datos backend Backend.addMessage(idConversacion, mensajeCifrado, nonceMensaje, marcaTiempo)

9.4 Propiedades del Chat

Visibilidad de Metadatos: El servidor conoce:
  • Quién está en qué conversaciones
  • Marcas de tiempo de mensajes
  • Longitudes aproximadas de mensajes
Esto es similar a la visibilidad de metadatos del lado del servidor de Signal.

9.5 Mejoras Futuras

Mejoras potenciales para versiones futuras:

10. Detalles de Implementación

10.1 Stack Tecnológico

Componente Tecnología
Frontend React + TypeScript
Biblioteca Cripto Web Crypto API + ml-kem (WebAssembly)
Backend Base de Datos Cloud, Almacenamiento de Objetos, Servicio de Autenticación, Funciones Serverless
Autenticación WebAuthn, FIDO2, OAuth 2.0

10.2 Implementación ML-KEM-768

Usamos la biblioteca JavaScript ml-kem, que proporciona:

10.3 Generación de Números Aleatorios

Toda aleatoriedad criptográfica usa crypto.getRandomValues():

function generarBytesAleatorios(longitud: number): Uint8Array { const arreglo = new Uint8Array(longitud); crypto.getRandomValues(arreglo); return arreglo; }

10.4 Manejo Seguro de Memoria

JavaScript no proporciona control explícito de memoria, pero seguimos mejores prácticas:

function borradoSeguro(arreglo: Uint8Array): void { arreglo.fill(0); }

10.5 Manejo de Errores

Los errores criptográficos se manejan cuidadosamente para prevenir fuga de información:

11. Análisis de Seguridad

11.1 Análisis de Amenazas

11.1.1 Compromiso del Servidor

Amenaza: Un atacante obtiene acceso completo a la infraestructura en la nube.

Impacto: Bajo. El atacante obtiene archivos cifrados, claves privadas cifradas, claves públicas, metadatos cifrados.

Mitigación: Sin frases de contraseña de usuario o claves de hardware, el atacante no puede descifrar. La arquitectura de conocimiento cero limita el daño a la recopilación de datos cifrados.

11.1.2 Escucha Pasiva de Red

Amenaza: Un atacante intercepta tráfico de red.

Impacto: Bajo. TLS protege el transporte, pero incluso el compromiso de TLS expone solo datos cifrados.

Mitigación: El cifrado a nivel de aplicación asegura que el texto plano nunca se transmita. Metadatos cifrados.

11.1.3 Ataque de Computadora Cuántica

Amenaza: Una futura computadora cuántica intenta romper el cifrado.

Impacto: Bajo para datos protegidos con ML-KEM-768. Seguridad del cifrado simétrico (AES-256) reducida pero aún fuerte.

Mitigación: ML-KEM-768 basado en problemas de retículas resistentes a algoritmos cuánticos conocidos. AES-256 proporciona 128 bits de seguridad contra ataques cuánticos (algoritmo de Grover), suficiente para la mayoría de los casos de uso.

11.1.4 Frase de Contraseña Débil

Amenaza: El usuario elige frase de contraseña débil, el atacante realiza fuerza bruta fuera de línea.

Impacto: Alto si tiene éxito. El atacante descifra la clave privada y obtiene acceso a todos los archivos.

Mitigación:

11.1.5 Phishing

Amenaza: Usuario engañado para ingresar frase de contraseña en sitio malicioso.

Impacto: Alto. El atacante obtiene la frase de contraseña y puede descifrar la clave privada.

Mitigación:

11.2 Fortaleza Criptográfica

Primitiva Seguridad Clásica Seguridad Cuántica
ML-KEM-768 192 bits 192 bits (Nivel NIST 3)
AES-256-GCM 256 bits 128 bits (Grover)
Argon2id (64 MiB) Depende de frase de contraseña Depende de frase de contraseña

11.3 Limitaciones Conocidas

  1. Fuga de Metadatos: Tamaños de archivos, marcas de tiempo, relaciones de compartir visibles al servidor
  2. Secreto Hacia Adelante: El chat no implementa secreto hacia adelante perfecto (sin ratcheting)
  3. Fortaleza de Frase de Contraseña: La seguridad del sistema está limitada por la fortaleza de la frase de contraseña elegida por el usuario
  4. Seguridad del Navegador: Depende del sandboxing del navegador y la implementación de Web Crypto API
  5. Sin Negabilidad: Los mensajes cifrados proporcionan autenticación pero no negabilidad
  6. Análisis de Tráfico: Patrones de actividad (cargas, descargas, inicios de sesión) observables por el servidor

11.4 Auditoría y Verificación

SeraVault es de código abierto, permitiendo auditorías de seguridad independientes:

12. Referencias

  1. NIST FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard. https://csrc.nist.gov/pubs/fips/203/final
  2. NIST Post-Quantum Cryptography: Algoritmos Seleccionados 2024. https://csrc.nist.gov/projects/post-quantum-cryptography
  3. AES-GCM: Recomendación para Modos de Cifrado por Bloques: Galois/Counter Mode (GCM) y GMAC. NIST SP 800-38D.
  4. WebAuthn: Web Authentication: An API for accessing Public Key Credentials Level 2. Recomendación W3C.
  5. Argon2: Argon2: the memory-hard function for password hashing. Ganador Password Hashing Competition (2015). Ganador PHC
  6. Web Crypto API: Recomendación W3C. https://www.w3.org/TR/WebCryptoAPI/
  7. Algoritmo de Grover: A fast quantum mechanical algorithm for database search. L.K. Grover, 1996.
  8. Algoritmo de Shor: Polynomial-Time Algorithms for Prime Factorization and Discrete Logarithms on a Quantum Computer. P.W. Shor, 1997.
  9. Learning With Errors: On lattices, learning with errors, random linear codes, and cryptography. O. Regev, 2005.