Cifrado de Extremo a Extremo

Cifrado híbrido RSA + AES-256-GCM. Los mensajes se cifran en el cliente — el servidor nunca ve el texto plano.

Modelo de Amenaza

Confiables: El operador (desk/CRM) y el cliente. Cada uno posee su propia clave privada.

No confiables: El backend de ixblix, la base de datos y los atacantes de red. El backend nunca posee una clave privada y nunca ve texto plano.

Lo que NO está protegido

  • Metadatos: quién habla con quién, cuándo y cuántos mensajes.
  • Almacenamiento del operador: el operador es responsable de proteger su clave privada.
  • Dispositivo del cliente: si está comprometido, la clave privada puede ser robada.

Esquema Criptográfico

PropósitoAlgoritmoParámetros
Envoltura de claveRSA-OAEP2048-bit, SHA-256
Contenido del mensajeAES-256-GCMClave 256-bit, IV 96-bit, tag 128-bit

Cada mensaje usa una clave nueva AES-256-GCM. Esa clave AES se envuelve (cifra) con la clave pública RSA del destinatario. Esto proporciona forward secrecy entre mensajes.

Auto-Lectura

La clave AES de cada mensaje se envuelve dos veces: una para el destinatario y una para la propia clave pública del remitente. Esto permite que cada lado lea sus propios mensajes enviados.

Envelope del Mensaje

CampoDescripción
contentCiphertext AES-256-GCM (base64).
ivVector de inicialización AES-GCM de 96 bits (base64).
authTagTag de autenticación AES-GCM de 128 bits (base64).
encryptedKeyClave AES envuelta por la clave RSA pública del destinatario.
selfEncryptedKeyClave AES envuelta por la propia clave RSA del remitente.
keyIdIdentificador de la clave pública del remitente.

Flujo de Intercambio de Claves

  1. El operador genera un par de claves RSA persistente y registra la clave pública vía PUT /api/companies/encryption-key.
  2. El operador crea una conversación. El backend hace snapshot de la clave activa de la empresa.
  3. El cliente abre el deeplink. El navegador genera un par de claves RSA. La clave privada queda en IndexedDB.
  4. El cliente registra la clave pública vía POST /api/conversations/{token}/key.
  5. ixblix envía un webhook CUSTOMER_JOINED con la clave pública del cliente.
  6. Ambos lados ahora pueden cifrar mensajes el uno para el otro.

Ejemplo de Cifrado

TypeScript (SDK)
import { encryptToRecipient } from '@ixblix/sdk-js';

const envelope = encryptToRecipient(
  '¡Hola desde Acme Corp!',
  customerPublicKeySpki,
  operatorKey.keyId,
  operatorKey.publicKeySpki,
);

// envelope.content — ciphertext en base64
// envelope.iv — IV en base64
// envelope.authTag — tag de autenticación en base64
// envelope.encryptedKey — clave AES envuelta para el cliente en base64
// envelope.selfEncryptedKey — clave AES envuelta para sí mismo en base64
// envelope.keyId — id de la clave del operador