Saltar a contenido

Investigacion: Cifrado de Perfil e Identificacion para MedTime

Identificador: INV-008 Version: 1.0.0 Fecha: 2025-12-05 Autor: SpecQueen Solicitado por: Director del Proyecto - Iteracion 13 Estado: Completado Tipo: Investigacion de Seguridad y Privacidad


1. Resumen Ejecutivo

Esta investigacion analiza la viabilidad y las implicaciones de cifrar las categorias de "Perfil" e "Identificacion" del usuario en MedTime, con el objetivo de minimizar la exposicion de datos sensibles que el servidor puede ver. Se evaluan tecnicas criptograficas avanzadas, desafios tecnicos, y se proponen soluciones practicas para V1.0 y versiones futuras.

1.1. Conclusion Principal

Aspecto Viabilidad Recomendacion V1.0
Cifrado completo de perfil Alta complejidad Modelo hibrido
Cifrado de identificadores Media complejidad Parcial con pseudonimos
Busqueda sobre datos cifrados Baja viabilidad Solo client-side
Recuperacion de cuenta Critico Split-key + Recovery

2. Estado Actual: Datos de Perfil e Identificacion en MedTime

2.1. Taxonomia de Datos Actuales

Segun la arquitectura documentada en MTS-USR-001 y MTS-PRI-001, MedTime maneja las siguientes categorias de datos personales:

2.1.1. Categoria: Identificacion (ID)

Campo Sensibilidad Cifrado Actual Uso por Servidor
email PII Alta AES-256 en reposo Autenticacion, recuperacion
telefono PII Alta AES-256 en reposo MFA, alertas SMS
nombre PII Media AES-256 en reposo Personalizacion UI
apellidos PII Media AES-256 en reposo Reportes, compartir
fecha_nacimiento PII Media AES-256 en reposo Calculos de edad, dosis
foto_perfil PII Alta AES-256 en reposo UI, compartir con medicos

2.1.2. Categoria: Perfil Medico (PHI)

Campo Sensibilidad Cifrado Actual Uso por Servidor
tipo_sangre PHI E2E (Nivel 2) Solo cliente descifra
alergias PHI Critica E2E (Nivel 1) Solo cliente descifra
condiciones_cronicas PHI Critica E2E (Nivel 1) Solo cliente descifra
peso PHI E2E (Nivel 2) Solo cliente descifra
altura PHI E2E (Nivel 2) Solo cliente descifra
notas_medicas PHI Critica E2E (Nivel 1) Solo cliente descifra

2.1.3. Categoria: Preferencias del Sistema

Campo Sensibilidad Cifrado Actual Uso por Servidor
idioma Baja Sin cifrar Localizacion
zona_horaria Baja Sin cifrar Calculos de horarios
formato_hora Baja Sin cifrar Presentacion
tema Baja Sin cifrar UI
unidades Baja Sin cifrar Conversiones

2.2. Modelo de Cifrado Actual (INV-001)

Segun la investigacion INV-001: Cifrado E2E Zero Knowledge, MedTime implementa un modelo hibrido de tres niveles:

NIVEL 1: Datos Super-Sensibles (E2E)
- Notas personales sobre medicamentos
- Fotos de recetas con datos visibles
- Mensajes con medicos
-> Cifrado E2E, solo paciente descifra

NIVEL 2: Datos Sensibles (Cifrado estandar)
- Lista de medicamentos
- Historial de tomas
- Mediciones de salud
-> Cifrado AES-256, MedTime puede acceder con autorizacion

NIVEL 3: Metadata (Sin cifrar)
- Timestamps de acceso
- Eventos de sincronizacion
- Logs de auditoria
-> Necesarios para cumplimiento

2.3. Brecha Identificada

La brecha actual es que los datos de identificacion (email, nombre, telefono) permanecen en Nivel 2 o 3, lo que significa que:

  1. El servidor puede leerlos para operaciones de autenticacion
  2. En caso de brecha del servidor, estos datos estarian expuestos
  3. El principio "zero-knowledge" no se aplica completamente

3. Tecnicas de Cifrado Aplicables

3.1. Cifrado Simetrico (AES-256-GCM)

3.1.1. Descripcion

AES-256-GCM es el estandar actual de MedTime para cifrado de datos en reposo. Proporciona confidencialidad y autenticacion integrada.

3.1.2. Parametros Recomendados (NIST SP 800-132)

Parametro Valor Justificacion
Algoritmo AES-256-GCM NIST approved, FIPS 140-2
Nonce 96 bits, aleatorio Nunca reutilizar
Tag 128 bits Autenticacion integrada
Key derivation Argon2id o PBKDF2 Ver seccion 2.3

3.1.3. Aplicacion a Perfil

Flujo de cifrado:
1. Usuario ingresa datos de perfil
2. Cliente deriva clave de cifrado de master key
3. Cliente cifra datos con AES-256-GCM
4. Cliente envia datos cifrados a servidor
5. Servidor almacena blob opaco

3.1.4. Ventajas

  • Alto rendimiento (instrucciones AES-NI en hardware)
  • Amplio soporte en todas las plataformas
  • Cumple NIST y FIPS

3.1.5. Desventajas

  • Clave simetrica debe compartirse para compartir datos
  • No permite busqueda sobre datos cifrados
  • Requiere gestion cuidadosa de nonces

3.2. Cifrado Asimetrico (RSA, ECC)

3.2.1. RSA-4096

Aspecto Especificacion
Tamano de clave 4096 bits minimo
Padding OAEP con SHA-256
Uso Intercambio de claves, firmas

3.2.2. ECC (Curve25519/P-256)

Aspecto Especificacion
Curva preferida Curve25519 (X25519)
Curva alternativa NIST P-256 (secp256r1)
Uso Key agreement (ECDH), firmas (EdDSA)

3.2.3. Aplicacion a Perfil e Identificacion

sequenceDiagram
    participant U as Usuario
    participant D as Dispositivo
    participant S as Servidor MedTime

    U->>D: Crea cuenta
    D->>D: Genera par de claves (pub/priv)
    D->>S: Registra clave publica
    D->>D: Cifra perfil con clave publica propia
    D->>S: Sube perfil cifrado
    Note over S: Servidor NO puede descifrar

    U->>D: Solicita ver perfil
    D->>S: Solicita blob cifrado
    S->>D: Devuelve blob
    D->>D: Descifra con clave privada
    D->>U: Muestra datos

3.2.4. Ventajas

  • Permite compartir datos sin compartir clave maestra
  • Forward secrecy con ECDHE
  • Firmas digitales para autenticidad

3.2.5. Desventajas

  • Mas lento que cifrado simetrico
  • Claves privadas requieren proteccion rigurosa
  • Perdida de clave privada = perdida de datos

3.3. Derivacion de Claves

3.3.1. PBKDF2 (NIST SP 800-132)

Parametros recomendados:
- PRF: HMAC-SHA256
- Iteraciones: minimo 600,000 (2025)
- Salt: 128 bits, aleatorio por usuario
- Output: 256 bits

Cumplimiento: FIPS 140-2 validated, requerido para HIPAA Safe Harbor.

3.3.2. Argon2id (RFC 9106)

Parametros recomendados para movil:
- Variante: Argon2id (resistente a side-channel y GPU)
- Memoria: 64 MiB (compromiso movil/desktop)
- Iteraciones: 3
- Paralelismo: 4
- Salt: 128 bits
- Output: 256 bits

Advertencia iOS: Segun Bitwarden, valores de memoria mayores a 64 MiB causan warnings en iOS autofill.

3.3.3. Recomendacion MedTime

Plataforma KDF Primario KDF Fallback
iOS Argon2id (64 MiB) PBKDF2 (600K)
Android Argon2id (64 MiB) PBKDF2 (600K)
Web Argon2id (64 MiB) PBKDF2 (600K)

3.4. Cifrado Homomorfico (FHE/PHE)

3.4.1. Estado del Arte 2025

Segun investigaciones recientes (MDPI 2025, Springer 2025), el cifrado homomorfico ha avanzado significativamente pero presenta limitaciones practicas:

Esquema Tipo Operaciones Performance
CKKS Aproximado Suma, multiplicacion, rotacion ~100ms por operacion
BFV Exacto Suma, multiplicacion (enteros) ~50ms por operacion
TFHE Completo Operaciones booleanas Segundos por operacion

3.4.2. Aplicaciones en Healthcare

Casos de uso documentados (arXiv 2501.04058):

  • K-means clustering para segmentacion de pacientes (99.2% accuracy vs plaintext)
  • Regresion logistica para prediccion de riesgo
  • Analisis multiinstitucional con datos distribuidos

3.4.3. Evaluacion para MedTime V1.0

Caso de Uso Viabilidad FHE Alternativa
Busqueda de email No viable (latencia) Hash determinista + lookup
Busqueda de nombre No viable Indice cifrado client-side
Calculos de adherencia Posible pero complejo Calculos client-side
Analytics agregados Futuro (V2.0+) Differential privacy

Recomendacion: FHE no es viable para V1.0 de MedTime debido a:

  1. Overhead computacional significativo en dispositivos moviles
  2. Complejidad de implementacion
  3. Librerias no maduras para produccion

Para V2.0+: Explorar CKKS para analytics agregados con consentimiento.

3.5. Blind Signatures para Autenticacion Anonima

3.5.1. Concepto

Las firmas ciegas permiten autenticar un usuario sin que el servidor conozca la identidad real. El servidor firma un "token cegado" que el cliente puede usar para demostrar autenticacion sin revelar quien es.

3.5.2. Implementaciones Actuales (2025)

Segun Privacy Pass IETF y IEEE 2024:

Sistema Uso Basado en
Privacy Pass CAPTCHAs, VPNs RSA Blind Signatures
iCloud Private Relay Anonimato en Apple RSA Blind Signatures
Google VPN (legacy) Anonimato de usuarios Blind Signatures
FIDO Anonymous Auth WebAuthn anonimo Blind Signatures

3.5.3. Aplicacion a MedTime

flowchart TD
    A[Usuario quiere autenticar] --> B[Cliente genera token aleatorio]
    B --> C[Cliente aplica factor de cegado]
    C --> D[Envia token cegado a servidor]
    D --> E[Servidor firma token cegado]
    E --> F[Cliente remueve factor de cegado]
    F --> G[Token firmado sin que servidor sepa contenido]
    G --> H[Cliente usa token para acceso anonimo]

3.5.4. Casos de uso en MedTime

  1. Acceso a catalogo de medicamentos: Usuario consulta sin revelar identidad
  2. Analytics anonimos: Enviar datos de uso sin identificar usuario
  3. Verificacion de tier sin identificar: Probar que es Pro/Perfect sin revelar quien

3.5.5. Limitaciones

  • No reemplaza autenticacion para datos personalizados
  • Complejo de implementar correctamente
  • Requiere infraestructura adicional

Recomendacion V1.0: No prioritario. Considerar para V2.0 para analytics y catalogo.


4. Desafios Tecnicos

4.1. Recuperacion de Cuenta sin Acceso a Datos

4.1.1. El Problema Fundamental

Paradoja de la recuperacion zero-knowledge:
- Si el servidor puede recuperar tu cuenta, puede ver tus datos
- Si el servidor NO puede ver tus datos, NO puede recuperar tu cuenta

4.1.2. Soluciones Existentes

Solucion Descripcion Riesgo de Perdida
Recovery Key (24 palabras) Usuario guarda clave offline Alto si pierde key
Social Recovery N de M contactos pueden recuperar Medio (colusion)
Hardware Key YubiKey, Ledger como backup Medio si pierde device
Time-locked Recovery Recuperacion tras N dias Bajo, pero lento
Trusted Third Party Escrow Servicio externo guarda parte de clave Bajo, pero reduce zero-knowledge

4.1.3. Modelo Propuesto para MedTime: Split-Key + Recovery

flowchart TD
    A[Usuario crea cuenta] --> B[Generar Master Key]
    B --> C[Dividir Master Key en 3 partes]
    C --> D1[Parte 1: Derivada de password]
    C --> D2[Parte 2: Recovery Key 24 palabras]
    C --> D3[Parte 3: Cifrada con clave de dispositivo]

    D1 --> E[Para login normal]
    D2 --> F[Usuario guarda offline]
    D3 --> G[En Keychain/Keystore]

    H[Recuperacion] --> I{Tiene Recovery Key?}
    I -->|Si| J[Reconstruir con Recovery Key + nuevo password]
    I -->|No| K{Tiene dispositivo anterior?}
    K -->|Si| L[Exportar desde dispositivo]
    K -->|No| M[DATOS PERDIDOS]

4.2. Busqueda y Sincronizacion con Datos Cifrados

4.2.1. El Problema

Si el email esta cifrado E2E, el servidor no puede:

  1. Buscar usuarios por email para login
  2. Enviar emails de recuperacion
  3. Verificar unicidad de email

4.2.2. Soluciones

Tecnica Descripcion Limitacion
Blind Index Hash determinista del email para busqueda Vulnerable a ataques de diccionario
Searchable Encryption Cifrado que permite busquedas Alto overhead, patentado
Client-side Search Descarga y busca localmente No escala
Pseudonimo Usar ID aleatorio, mapeo local Complejidad de sincronizacion

4.2.3. Solucion Propuesta: Blind Index con Salt Global

Proceso:
1. email_hash = HMAC-SHA256(global_salt, normalize(email))
2. Servidor almacena email_hash (sin poder revertir)
3. Login: cliente envia email_hash
4. Servidor busca por email_hash
5. Servidor devuelve blob cifrado (no puede leer email real)

Proteccion adicional:
- global_salt rota anualmente
- Rate limiting en busquedas
- Audit log de todas las consultas

Limitacion: Vulnerable si atacante tiene acceso a global_salt + base de datos. Mitigacion: HSM para global_salt.

4.3. Verificacion de Identidad sin Exponer Datos

4.3.1. El Problema

Para verificar que un usuario es quien dice ser (en recuperacion, soporte, etc.), tradicionalmente se piden datos personales que el servidor no deberia poder ver.

4.3.2. Soluciones Zero-Knowledge

Tecnica Descripcion Complejidad
ZK Proofs Usuario prueba conocimiento sin revelar Alta
Preguntas de seguridad cifradas Respuestas hasheadas client-side Media
Verificacion biometrica local Face/Touch ID valida identidad Baja
Hardware attestation Device bound credentials Media

4.3.3. Propuesta MedTime: Verificacion Escalonada Zero-Knowledge

Nivel 1 (Automatico):
- Biometria local (Face ID/Touch ID)
- Device attestation (mismo dispositivo)
- Recovery Key

Nivel 2 (Semi-automatico):
- Preguntas de seguridad (hash client-side)
- Selfie + liveness check (procesado localmente)
- Codigo a contacto de emergencia

Nivel 3 (Manual):
- Documento de identidad (revision humana)
- Videollamada (casos excepcionales)
- Notaria electronica (para herencia/tutela)

5. Soluciones Propuestas

5.1. Derivacion de Claves desde Autenticacion Social (Google/Apple)

5.1.1. Concepto

Usar los tokens de OAuth de Google/Apple Sign-In como entropia adicional para derivar claves de cifrado, sin que Google/Apple tengan acceso a la clave final.

5.1.2. Arquitectura Propuesta

sequenceDiagram
    participant U as Usuario
    participant A as App MedTime
    participant G as Google/Apple
    participant S as Servidor MedTime

    U->>A: Sign in with Google/Apple
    A->>G: OAuth flow
    G->>A: id_token (JWT con sub claim)
    A->>A: user_id = hash(sub + app_specific_salt)
    A->>A: partial_key = KDF(id_token.sub + device_secret)
    A->>A: master_key = KDF(partial_key + user_password)
    A->>S: Registrar con user_id (sin id_token)
    Note over S: Servidor solo conoce user_id hasheado

5.1.3. Propiedades

  • Google/Apple no conocen la master_key (requiere password)
  • Servidor no puede derivar master_key (requiere id_token.sub)
  • Usuario necesita password + cuenta social para acceso

5.1.4. Limitaciones

  • Dependencia de proveedor OAuth
  • Si Google/Apple cambia sub claim, problemas de acceso
  • Complejidad de implementacion

Recomendacion: Opcion avanzada para usuarios Pro/Perfect. No default.

5.2. Split-Key Architecture

5.2.1. Diseño

Master Key = Reconstruct(Key_Password, Key_Device, Key_Recovery)

Donde:
- Key_Password = KDF(user_password, salt_user)
- Key_Device = Almacenada en Secure Enclave/Keystore
- Key_Recovery = 24 palabras BIP39 (usuario guarda offline)

Esquema de secreto compartido: Shamir's Secret Sharing (2-of-3)

5.2.2. Implementacion

Registro:
1. Generar master_key aleatorio (256 bits)
2. Dividir con Shamir(3,2) en shares A, B, C
3. Share A = cifrar con KDF(password)
4. Share B = almacenar en Secure Enclave
5. Share C = convertir a 24 palabras BIP39
6. Usuario DEBE guardar Share C offline

Login normal (sin recuperacion):
1. Usuario ingresa password
2. App obtiene Share A (derivado de password)
3. App obtiene Share B (de Secure Enclave)
4. Reconstruir master_key con A + B

Recuperacion (nuevo dispositivo):
1. Usuario ingresa password (Share A)
2. Usuario ingresa 24 palabras (Share C)
3. Reconstruir master_key con A + C
4. Generar nuevo Share B en nuevo dispositivo

5.2.3. Beneficios

Escenario Acceso Requiere
Uso normal OK Password + Dispositivo
Nuevo dispositivo OK Password + Recovery Key
Olvido password OK Dispositivo + Recovery Key
Perdida dispositivo + password OK Recovery Key (resetear password)
Perdida de todo PERDIDO N/A

5.3. Client-Side Encryption con Recovery Keys

5.3.1. Modelo Completo

flowchart TD
    subgraph "Creacion de Cuenta"
        A1[Usuario crea password] --> A2[Generar master_key]
        A2 --> A3[Generar Recovery Key 24 palabras]
        A3 --> A4[Cifrar master_key con password]
        A4 --> A5[Cifrar master_key con Recovery Key]
        A5 --> A6[Subir ambos blobs cifrados]
    end

    subgraph "Cifrado de Perfil"
        B1[Usuario ingresa datos perfil] --> B2[Derivar profile_key de master_key]
        B2 --> B3[Cifrar con AES-256-GCM]
        B3 --> B4[Subir blob cifrado]
    end

    subgraph "Acceso a Datos"
        C1[Usuario hace login] --> C2[Descargar blob cifrado de master_key]
        C2 --> C3[Descifrar con password]
        C3 --> C4[Derivar profile_key]
        C4 --> C5[Descargar blob de perfil]
        C5 --> C6[Descifrar con profile_key]
        C6 --> C7[Mostrar datos]
    end

6. Implicaciones para MedTime

6.1. Datos que DEBEN Permanecer Visibles

Estos datos son necesarios para operacion del sistema y no pueden cifrarse E2E:

Dato Razon Mitigacion
email_hash (Blind Index) Busqueda para login Hash no reversible
telefono_hash Busqueda para MFA/SMS Hash no reversible
tier_suscripcion Facturacion, limites Dato no sensible
fecha_registro Auditoria Dato no sensible
ultimo_acceso Seguridad Dato no sensible
pais Regulaciones aplicables Dato de baja sensibilidad
idioma Localizacion Dato de baja sensibilidad
timestamps_sync Sincronizacion Metadata operativa

6.2. Datos que PUEDEN Cifrarse Completamente

Estos datos pueden cifrarse E2E sin impacto en funcionalidad del servidor:

Dato Nivel de Cifrado Notas
nombre_completo E2E Solo descifrado client-side
fecha_nacimiento E2E Calculos de edad client-side
direccion E2E Nunca usado por servidor
foto_perfil E2E Almacenada como blob cifrado
tipo_sangre E2E (ya implementado) PHI
alergias E2E (ya implementado) PHI critico
condiciones_cronicas E2E (ya implementado) PHI critico
notas_medicas E2E (ya implementado) PHI critico
contactos_emergencia.nombre E2E Solo necesita telefono para alertas
preferencias_personalizadas E2E Tema, sonidos, etc.

6.3. Datos en Zona Gris (Requieren Decision)

Dato Actualmente Opcion A: Visible Opcion B: Cifrado E2E
email (texto claro) Nivel 2 Necesario para emails transaccionales Solo hash, emails via tercero
telefono (texto claro) Nivel 2 Necesario para SMS directos Solo hash, SMS via callback
peso/altura Nivel 2 Podria usarse para analytics Client-side calculos

Recomendacion: Opcion B para todos. Usar servicios de terceros (Twilio, SendGrid) que no necesitan conocer email/telefono real.

6.4. Trade-offs de Usabilidad vs Privacidad

Funcionalidad Con E2E Completo Sin E2E en Identificacion
Login con email Blind index (funciona) Email visible (funciona)
Recuperacion por email No directa, via Recovery Key Email de recuperacion
SMS de verificacion Callback con token SMS directo
Soporte tecnico No puede ver datos usuario Puede ver datos
Buscar usuario por nombre No posible server-side Posible
Compartir con nombre Muestra "Usuario #12345" Muestra "Juan Perez"
Personalizacion emails Solo "Hola usuario" "Hola Juan"

7. Recomendaciones

7.1. Para V1.0 de MedTime

7.1.1. Implementacion Inmediata (Prioridad Alta)

Item Descripcion Esfuerzo
Blind Index para email/telefono Hash no reversible para busqueda 2 semanas
Cifrado E2E de nombre/apellidos Client-side encryption 1 semana
Cifrado E2E de fecha_nacimiento Con calculo de edad client-side 1 semana
Cifrado E2E de foto_perfil Blob cifrado 1 semana
Recovery Key obligatoria (Pro/Perfect) 24 palabras BIP39 2 semanas
Migracion de KDF a Argon2id Para nuevas cuentas 1 semana

7.1.2. Implementacion Diferida (Prioridad Media)

Item Descripcion Esfuerzo Target
Split-Key Architecture Shamir 2-of-3 4 semanas V1.1
Derivacion desde OAuth Google/Apple Sign-In integration 3 semanas V1.2
Cifrado E2E de contactos_emergencia.nombre Solo telefono visible 1 semana V1.1

7.2. Para Versiones Futuras (V2.0+)

Feature Descripcion Complejidad
Blind Signatures Acceso anonimo a catalogo Alta
FHE para Analytics Estadisticas sobre datos cifrados Muy Alta
Social Recovery N-of-M contactos para recuperar Media
Hardware Key Support YubiKey, Ledger como factor Media
Anonymous Credentials Prueba de tier sin identificar Alta

7.3. Matriz de Decision por Tier

Caracteristica Free Pro Perfect
Datos 100% locales Si No No
Cifrado E2E de PHI Si (local) Si Si
Cifrado E2E de Perfil Si (local) Recomendado Obligatorio
Recovery Key N/A (local) Obligatoria Obligatoria
Split-Key N/A Opcional Default
MFA PIN/Biometria Obligatorio Obligatorio
Blind Index N/A Si Si

7.4. Advertencias y Consentimiento

El usuario debe ser claramente informado:

+--------------------------------------------------+
| CIFRADO AVANZADO DE PERFIL                        |
+--------------------------------------------------+

Al habilitar el cifrado completo de tu perfil:

[!] Tus datos personales (nombre, fecha de nacimiento,
    foto) seran cifrados y SOLO TU podras verlos.

[!] Si pierdes tu Recovery Key Y tu password,
    estos datos seran IRRECUPERABLES.

[!] El soporte tecnico NO podra ayudarte a
    recuperar tu nombre o foto.

BENEFICIO:
Ni siquiera MedTime puede ver tu nombre real.
Solo tu puedes descifrar tu perfil.

[ ] Entiendo los riesgos y deseo activar
    el cifrado completo de mi perfil

[Cancelar]              [Activar Cifrado]
+--------------------------------------------------+

8. Referencias

8.1. Estandares NIST

8.2. Cifrado Homomorfico en Healthcare

8.3. Zero-Knowledge y Cifrado Client-Side

8.4. Blind Signatures y Autenticacion Anonima

8.5. Key Derivation Functions

8.6. Documentos MedTime Relacionados


9. Anexo: Implementacion Tecnica Detallada

9.1. Estructura de Datos Cifrados (Propuesta)

{
  "version": "1.0",
  "algorithm": "AES-256-GCM",
  "kdf": "argon2id",
  "kdf_params": {
    "memory": 65536,
    "iterations": 3,
    "parallelism": 4
  },
  "encrypted_profile": {
    "nonce": "base64_encoded_96bit_nonce",
    "ciphertext": "base64_encoded_encrypted_data",
    "tag": "base64_encoded_128bit_auth_tag"
  },
  "metadata": {
    "created_at": "2025-12-05T10:00:00Z",
    "updated_at": "2025-12-05T10:30:00Z",
    "key_version": 1
  }
}

9.2. Flujo de Blind Index para Email

# Pseudocodigo - NO usar en produccion sin revision de seguridad

import hashlib
import hmac

def create_blind_index(email: str, global_salt: bytes) -> str:
    """
    Crea un blind index para busqueda de email sin revelar el email real.

    IMPORTANTE: global_salt debe estar en HSM y rotarse anualmente.
    """
    # Normalizar email
    normalized = email.lower().strip()

    # Crear HMAC (no reversible sin conocer global_salt)
    index = hmac.new(
        key=global_salt,
        msg=normalized.encode('utf-8'),
        digestmod=hashlib.sha256
    ).hexdigest()

    # Truncar para reducir riesgo de colisiones como ataque
    return index[:32]  # 128 bits suficientes para unicidad

def lookup_user(email: str, global_salt: bytes, db) -> User:
    """Buscar usuario por blind index."""
    blind_index = create_blind_index(email, global_salt)
    return db.users.find_one({"email_index": blind_index})

9.3. Recovery Key BIP39

# Pseudocodigo - Usar libreria bip39 verificada

from mnemonic import Mnemonic

def generate_recovery_key() -> tuple[str, bytes]:
    """
    Genera Recovery Key de 24 palabras y su entropia.
    """
    mnemo = Mnemonic("english")

    # 256 bits de entropia = 24 palabras
    words = mnemo.generate(strength=256)

    # Derivar seed de las palabras
    seed = mnemo.to_seed(words, passphrase="")

    return words, seed[:32]  # 256 bits para AES-256

def verify_recovery_key(words: str) -> bool:
    """Valida checksum de Recovery Key."""
    mnemo = Mnemonic("english")
    return mnemo.check(words)

Documento generado por SpecQueen - "La privacidad no es un feature, es un derecho fundamental. Tus datos seran asimilados... en un bunker criptografico impenetrable."