Plata · Beta 4 · Octubre 2026
Hoja técnica de seguridad.
Qué cifra Plata, qué ve el servidor y qué todavía no existe. Está escrita desde el código y puede contrastarse con él: todo está en el repositorio público (código disponible para consulta, con licencia propietaria).
01 · En cinco líneas
Cómo está pensada.
Todo funciona en el dispositivo. No hay cuenta obligatoria, ni conexión al banco, ni analítica.
Si se activa Plata Cloud, el perfil se cifra en el dispositivo con AES-GCM de 256 bits antes de salir.
La clave nace de 128 bits aleatorios, guardados como una frase de 12 palabras que solo tiene la persona.
Un Cloudflare Worker con KV (y un Durable Object para los contadores y códigos) guarda texto cifrado y unos metadatos mínimos, descritos abajo.
La app, el servidor y esta documentación se pueden consultar en GitHub (código disponible, no código abierto).
02 · Claves y cifrado
Lo que ocurre en el dispositivo.
| Semilla | 128 bits aleatorios (crypto.getRandomValues). Se muestra como frase de recuperación de 12 palabras. |
|---|---|
| Frase de recuperación | 12 palabras de una lista de 2048 (11 bits por palabra): 128 bits de semilla más 4 bits de suma de verificación, que detectan errores al escribirla. |
| Derivación de claves | HKDF con SHA-256 y sal fija plata-cloud-v1. Con info = data se obtiene la clave AES-GCM de 256 bits (no exportable en WebCrypto). Con info = check se obtiene una comprobación de 256 bits. |
| Cifrado de datos | El perfil se comprime con gzip y se cifra con AES-GCM: IV aleatorio de 96 bits en cada guardado y datos asociados plata1. El formato lleva un byte de versión. Desde la compilación 421, la revisión viaja dentro del cifrado: la app rechaza una copia vieja que el servidor intente hacer pasar por nueva. |
| Comprobación de clave | El servidor guarda la comprobación (check) para verificar que un dispositivo conoce la clave. Sale de la misma semilla por otra rama de HKDF y no permite obtener la clave de datos. |
| Llave de escritura | Otra rama de HKDF (write). El servidor guarda solo su hash y la exige para subir, reemplazar o borrar la copia y para cerrar las demás sesiones. Quien solo tiene acceso al correo puede ver el texto cifrado, pero no puede pisarlo ni borrarlo. |
| Por qué no PBKDF2 ni Argon2 | Esos algoritmos alargan contraseñas que elige una persona. Aquí la entrada no es una contraseña, es una semilla aleatoria de 128 bits, así que no hay nada que adivinar por diccionario y alargarla no aporta seguridad adicional. |
03 · Dispositivos nuevos
Iniciar sesión en otro dispositivo.
Un dispositivo nuevo se aprueba desde uno que ya está conectado, sin que la semilla pase por el servidor en claro.
| Intercambio | ECDH P-256 con claves efímeras en cada solicitud, más AES-GCM de 256 bits con datos asociados plata-link1. |
|---|---|
| Verificación humana | Comparación numérica con compromiso previo. El dispositivo activo se compromete con su clave efímera y un aleatorio antes de conocer el aleatorio del nuevo; el código de 6 dígitos depende de las dos claves y los dos aleatorios, y la persona lo compara en ambas pantallas. Quien esté en medio, incluido el servidor, no puede fabricar una clave con el mismo código: acierta 1 vez en un millón. |
| Papel del servidor | Solo retransmite los pasos del protocolo y la respuesta cifrada. Cada paso es atómico. |
04 · Servidor
Qué ve y qué guarda Plata Cloud.
Un Cloudflare Worker con almacenamiento KV. Es todo lo que el servidor puede ver:
| Perfil | Un bloque cifrado de hasta 1,5 MB por cuenta, con su número de revisión, la fecha, la plataforma y el tamaño. No hay forma de leer su contenido sin la frase de la persona. |
|---|---|
| Cuenta | El correo electrónico (necesario para enviar los códigos de acceso) y la comprobación de clave. Las llaves de almacenamiento usan un identificador derivado del correo con SHA-256 y una sal configurada en el servidor. |
| Sesiones | Token aleatorio guardado solo como hash. Dura 90 días. Desde Ajustes se pueden cerrar todas las demás sesiones (pide la frase). |
| Códigos de acceso | 6 dígitos, guardados como hash con sal, con vigencia de 10 minutos y un máximo de 5 intentos, contados de forma atómica (Durable Object): no se pueden probar en paralelo. Además, como máximo 15 fallos al día por correo. |
| Límite de abuso | Límite de solicitudes por hora y dirección IP (hash con sal), con vencimiento automático, en contadores atómicos que no gastan escrituras de KV. |
| Beta | En la beta algunas personas envían voluntariamente una copia de su archivo para análisis de uso, o un archivo del banco para enseñarle a Nazca. Es opcional y está explicado en la página de transparencia. |
05 · En el dispositivo
Qué queda guardado localmente.
| Almacenamiento | El perfil vive en el localStorage del navegador. No está cifrado en reposo: depende de la protección del propio dispositivo (bloqueo de pantalla y cifrado del sistema). |
|---|---|
| Sin conexión | La app funciona sin conexión mediante un service worker. |
| Terceros | La app no carga scripts de analítica ni de publicidad. Sus únicas conexiones externas son a Plata Cloud (cuando la persona activa la nube, se apunta a la lista de espera, envía una copia para análisis o manda un archivo a Nazca), una sola vez al puente de mudanza en plataapp.net, y los enlaces que la persona abre. |
| Borrado | Desde la app se pueden borrar los datos de la nube (con una verificación de 3 palabras de la frase, una espera de 5 segundos y, en el servidor, la llave de escritura) y los datos locales. |
06 · Lo que todavía no existe
Lo decimos nosotros primero.
- No hay una auditoría externa de seguridad. Preferimos que la primera sea la del equipo de Ciberseguridad del BCP.
- El sitio informativo todavía no tiene una Content-Security-Policy propia. La app sí: desde la compilación 421 solo ejecuta sus propios scripts (verificados por hash) y solo se conecta con Plata Cloud, y está pasando a su propio dominio, web.plataapp.net.
- Las pruebas de seguridad del servidor están en el repositorio (dev/tests), pero solo dos (intentos simultáneos contra un código y orígenes permitidos) corren de forma automática antes de publicar el servidor; el resto se ejecuta a mano.
- Si alguien pierde su frase de 12 palabras no hay recuperación de la copia en la nube, porque nadie más puede descifrarla. Un reinicio guiado por correo está planificado, pero no existe aún.
- No hay un SLA ni soporte con tiempos garantizados: hoy el soporte es pequeño y por correo.
07 · Cómo revisarlo
Está todo a la vista.
Repositorio: github.com/leoricharte/Plata. El cifrado está en dev/app/src/app.html (módulo de claves de Plata Cloud) y el servidor en dev/worker/worker.js.
Estamos disponibles para facilitar el repositorio y la documentación técnica a una revisión de código o una prueba de penetración por parte del equipo de Ciberseguridad del BCP.