Claves entre dispositivos: cómo entra un portátil nuevo sin que el servidor mire
Un dispositivo recién estrenado necesita la clave del documento, el servidor no debe verla y los dos extremos casi nunca coinciden conectados: es el problema de identidad sin servidor del nivel anterior, ahora con un secreto encima.
Una persona no es un participante criptográfico. Lo que firma, cifra y descifra es un dispositivo, y una persona corriente tiene tres o cuatro, los cambia cada pocos años, pierde alguno y hereda otros. Cualquier sistema cifrado de extremo a extremo tiene que responder por tanto a una pregunta que en un sistema con servidor se despachaba con una contraseña: cómo obtiene un portátil recién comprado la clave de un documento que se creó hace dos años, sin que el servidor pueda verla y sin que necesariamente exista ningún otro dispositivo encendido en ese momento. La respuesta no es una técnica sino una familia de técnicas con propiedades distintas, y elegir mal condena la experiencia del producto o su seguridad. Esta lección desmonta el problema en sus tres piezas —quién es miembro, qué canal autentica el traspaso y cómo se hace asíncrono— y termina mostrando que el fondo del asunto es exactamente el que ocupó el nivel anterior: atar una clave pública a alguien sin preguntarle a una autoridad.
- Modelar la identidad como un grupo de dispositivos y entender por qué esa indirección simplifica todo lo demás.
- Comparar los tres canales de traspaso de secreto por lo que autentican realmente y no por su comodidad.
- Entender el patrón de paquete de claves publicado por adelantado y por qué resuelve la asincronía.
- Identificar el punto exacto en el que reaparece la necesidad de confiar en alguien, y qué se hace con él.
- Valorar la recuperación ante pérdida de dispositivo como parte del diseño y no como añadido posterior.
El miembro es el dispositivo, y la persona es un grupo
El primer movimiento de diseño, y el que más problemas evita, consiste en dejar de tratar a la persona como una entidad criptográfica y tratarla como un grupo cuyos miembros son sus dispositivos. Cada dispositivo genera su propio par de claves y no lo saca nunca de su almacenamiento seguro; la persona es una agrupación con nombre que contiene a esos dispositivos; y los documentos conceden acceso a la persona, no a cada aparato. Es la idea que el proyecto de control de acceso local-first de Ink and Switch llama grupos transitivos: los dispositivos se gestionan detrás de un agente que actúa de intermediario, de modo que los documentos solo necesitan conocer a ese agente y no a cada uno de los aparatos que hay debajo.
La ventaja es de escala y de acoplamiento. Sin esa indirección, añadir un teléfono obliga a tocar todos los documentos a los que la persona tiene acceso, y quitarlo obliga a lo mismo; con ella, dar de alta un dispositivo es una operación dentro del grupo de la persona, y los cientos de documentos que le conceden permiso no se enteran. La desventaja es que introduce un nivel de indirección que hay que resolver al comprobar cualquier permiso, y que ese nivel puede anidarse: personas dentro de equipos dentro de organizaciones.
// La persona es un grupo; los documentos hablan con el grupo, no con los aparatos
const ana = {
id: 'ana',
miembros: [
{ dispositivo: 'portatil', firma: pkFirmaA, cifrado: pkCifradoA },
{ dispositivo: 'telefono', firma: pkFirmaB, cifrado: pkCifradoB }
]
};
// Conceder acceso menciona a ana, no a sus dos aparatos
conceder(documento, ana.id, 'lectura');
flowchart LR D1[portatil] --> A[agente ana] D2[telefono] --> A D3[portatil nuevo] --> A A --> DOC1[documento uno] A --> DOC2[documento dos] A --> DOC3[documento tres] style A fill:#cba6f7,color:#11111b style D3 fill:#f9e2af,color:#11111b
Tres canales para pasar el secreto y qué autentica cada uno
Con el modelo anterior, el problema se reduce a uno solo: cómo entra un dispositivo nuevo en el grupo de su dueña. Hay tres respuestas industriales y conviene juzgarlas por lo que autentican, que es distinto de lo cómodas que resultan.
La primera es la proximidad física. El dispositivo nuevo muestra un código en pantalla y el antiguo lo escanea, o ambos muestran una cadena corta que la persona compara con los ojos. Lo que autentica aquí es que las dos pantallas están delante de la misma persona, y esa es una garantía extraordinariamente fuerte porque no depende de ninguna red ni de ninguna autoridad. Es el mecanismo más sólido de los tres y el que peor escala: exige tener ambos aparatos a mano y encendidos, cosa que falla justo cuando más falta hace, que es cuando el aparato antiguo se ha roto o se ha perdido.
La segunda es un secreto que la persona recuerda o custodia: una frase de recuperación, una contraseña de la que se deriva una clave con una función de derivación cara, o un fichero guardado en un gestor. Lo que autentica es el conocimiento del secreto, y por tanto la seguridad del sistema entero queda acotada por la entropía de algo que un ser humano tiene que conservar durante años. Es el único mecanismo que funciona cuando no queda ningún dispositivo antiguo, y por eso todo sistema serio acaba teniendo uno, aunque lo esconda bien en la interfaz.
La tercera es la delegación a un tercero que ya está autenticado: un servicio de identidad corporativo, un dispositivo de otra persona del equipo que da el visto bueno, o un esquema de reparto del secreto entre varios contactos que deben coincidir para reconstruirlo. Lo que autentica es la confianza depositada en ese tercero, que puede ser mucha o poca según el caso, pero nunca es cero.
Existe una tentación fuerte de tratar la recuperación como una funcionalidad secundaria que ya se añadirá, y es un error de orden. En un sistema donde las claves no salen del dispositivo, perder el único dispositivo equivale a perder los datos de forma irreversible, y esa es una experiencia que ningún usuario perdona. Lo que ocurre entonces es que se añade a última hora un mecanismo de rescate mal pensado —una copia de la clave en el servidor, protegida por una contraseña corta— que se convierte en el punto más débil de todo el sistema y anula silenciosamente la propiedad que se quería vender. Diseñar la ruta de recuperación el primer día, y anunciar con claridad su fuerza, es lo que impide ese desenlace.
El paquete que se publica antes de que haga falta
Ninguno de los tres canales anteriores resuelve el problema de la asincronía, y ese es el requisito que define el escenario local-first. El dispositivo nuevo puede aparecer un martes por la noche cuando el resto del equipo duerme; quien tiene que darle acceso puede estar en un avión; y el traspaso tiene que completarse igualmente. La solución estándar consiste en invertir el orden: el dispositivo publica por adelantado todo lo necesario para que alguien le hable sin haber hablado nunca con él.
El protocolo del IETF para mensajería en grupo, publicado como RFC 9420, llama a ese objeto paquete de claves, y su función es exactamente esa: describir las capacidades de un cliente y publicar una clave a la que cualquiera puede cifrarle una invitación. Un miembro que ya está dentro toma ese paquete, construye un mensaje de bienvenida cifrado únicamente para él y lo deja en el servidor; el servidor lo guarda y lo entrega sin poder abrirlo, y el nuevo miembro lo recoge cuando aparezca. Ninguno de los dos extremos necesitó estar conectado a la vez.
// Lo que publica el dispositivo nuevo, firmado por el aparato que lo avala
const paquete = {
dispositivo: idPublico,
cifrado: pkCifrado, // para que le sellen la bienvenida
firma: pkFirma, // para que verifiquen lo que escriba despues
caduca: Date.now() + 30 * 86400 * 1000,
aval: firmaDe(portatilAntiguo, idPublico)
};
publicar(paquete); // el servidor solo lo custodia
// Un miembro que ya esta dentro sella la bienvenida y se desentiende
const bienvenida = await sellarPara(paquete.cifrado, {
claveDeGrupo: claveActual,
epoca: estado.epoca,
raizDelGrafoDeAcceso: raiz
});
depositar(bienvenida); // opaco para el servidor, esperando al destinatario
Proximidad
Autentica que dos pantallas están ante la misma persona. La garantía más fuerte y la que peor escala.
Secreto memorizado
Autentica conocimiento. Es la única vía cuando no queda ningún dispositivo antiguo, y acota la seguridad total.
Aval de un tercero
Autentica la confianza en quien avala. Cómodo en una organización, inaceptable para quien no confía en ella.
Paquete publicado
No autentica nada por sí solo: resuelve la asincronía y hereda la autenticación de quien firmó el aval.
La cuarta tarjeta es la que suele leerse mal y merece precisión. Publicar un paquete de claves no aporta autenticación: aporta disponibilidad. Quien recoge ese paquete del servidor tiene que decidir si la clave que contiene pertenece de verdad a quien dice, y esa decisión se apoya siempre en alguno de los tres canales anteriores, no en el paquete mismo. Si nadie la toma, un servidor malicioso puede sustituir el paquete por uno propio y convertirse en miembro del grupo con todos los honores, y el cifrado seguirá funcionando perfectamente mientras el atacante lee todo.
Es el problema del nivel anterior con un secreto encima
Llegados aquí conviene nombrar lo que ha pasado, porque es la conclusión de la lección. Todo el aparato criptográfico funciona sin ninguna autoridad central salvo en un punto: alguien tiene que afirmar que esta clave pública es la de esta persona. El propio RFC 9420 lo dice con claridad al describir su contexto, y es una de las frases más honestas de la especificación: el protocolo asume un servicio de autenticación en el que sí se confía, y en cambio asume un servicio de entrega en el que en general no se confía. La confidencialidad está protegida frente al que reparte los mensajes; la vinculación entre nombre y clave, no.
Ese es exactamente el problema del nivel anterior. Un identificador derivado de una clave se autocertifica pero no es legible ni memorizable; un nombre legible necesita a alguien que lo asigne; y las salidas conocidas son un registro público verificable de asignaciones, la verificación fuera de banda mediante huellas comparadas por las personas, o la aceptación explícita de confiar en primer uso con aviso llamativo cuando algo cambie. Ninguna elimina la confianza: la hacen auditable, que es distinto y mucho mejor que nada.
Merece la pena enunciar esto como principio porque explica de golpe por qué los productos cifrados que existen tienen la forma que tienen. La promesa intuitiva del cifrado extremo a extremo es que ya no hace falta confiar en nadie, y esa promesa es cierta para una cosa muy concreta: el contenido está protegido frente a cualquiera que no tenga la clave, incluido quien opera la infraestructura. Lo que la promesa no dice es que para llegar hasta ahí hubo que responder una pregunta previa que la criptografía no sabe responder sola: cuál es la clave de la persona con la que creo que estoy hablando. Esa pregunta no es matemática, es social, y por eso ningún algoritmo la cierra. Todo sistema cifrado tiene, en algún punto de su arranque, un acto de fe: un código escaneado, una huella comparada, un registro público consultado, una organización que dice que este empleado es este empleado, o simplemente la aceptación silenciosa de lo que devolvió el servidor la primera vez. La diferencia entre un diseño honesto y uno que solo lo parece no está en si ese acto de fe existe, porque existe siempre, sino en tres cosas: si está señalado con claridad, si el usuario tiene manera de verificarlo por su cuenta y si el sistema avisa cuando cambia. Los productos que hacen bien esto último son reconocibles porque muestran un aviso desagradable cuando la clave de un contacto se sustituye, y ese aviso es feo a propósito. Los que lo hacen mal cambian la clave en silencio, y en ese silencio cabe entero un ataque de suplantación que ninguna auditoría del algoritmo detectará jamás. De ahí la pregunta que conviene hacerle a cualquier sistema de este tipo antes que ninguna otra, incluido el propio: de dónde salió la primera clave pública que tu cliente aceptó como buena, y qué le pasa a todo el edificio si esa respuesta era falsa.
- Modela a una persona como grupo de dispositivos y comprueba cuántos documentos hay que tocar al añadir un aparato.
- Implementa el alta por proximidad con comparación de una cadena corta y mide cuántos segundos tarda una persona real.
- Añade el alta asíncrona mediante paquete publicado y verifica que funciona con el otro dispositivo apagado.
- Simula un servidor que sustituye el paquete publicado por uno propio y comprueba qué parte de tu sistema lo detecta.
- Diseña la ruta de recuperación sin ningún dispositivo antiguo y escribe con honestidad cuánta seguridad tiene.
- Añade el aviso de cambio de clave de un contacto y enséñaselo a alguien que no sepa qué significa.