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ósito | Algoritmo | Parámetros |
|---|---|---|
| Envoltura de clave | RSA-OAEP | 2048-bit, SHA-256 |
| Contenido del mensaje | AES-256-GCM | Clave 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
| Campo | Descripción |
|---|---|
content | Ciphertext AES-256-GCM (base64). |
iv | Vector de inicialización AES-GCM de 96 bits (base64). |
authTag | Tag de autenticación AES-GCM de 128 bits (base64). |
encryptedKey | Clave AES envuelta por la clave RSA pública del destinatario. |
selfEncryptedKey | Clave AES envuelta por la propia clave RSA del remitente. |
keyId | Identificador de la clave pública del remitente. |
Flujo de Intercambio de Claves
- El operador genera un par de claves RSA persistente y registra la clave pública vía
PUT /api/companies/encryption-key. - El operador crea una conversación. El backend hace snapshot de la clave activa de la empresa.
- El cliente abre el deeplink. El navegador genera un par de claves RSA. La clave privada queda en IndexedDB.
- El cliente registra la clave pública vía
POST /api/conversations/{token}/key. - ixblix envía un webhook
CUSTOMER_JOINEDcon la clave pública del cliente. - 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