Datos: un error de décadas en su estructura

Fuentes: You’re still signing data structures the wrong way

Durante décadas, la forma en que estructuramos y preparamos datos antes de aplicar algoritmos criptográficos como firmas, encriptación, MACs (Message Authentication Codes) o hashes, ha sido un problema sin una solución verdaderamente sólida. El problema principal radica en dos aspectos: primero, la codificación debe producir resultados canónicos (de manera que diferentes codificaciones no generen el mismo dato en memoria, evitando problemas como la maleabilidad de transacciones en Bitcoin); y segundo, el sistema de codificación debe abordar el crucial problema de la separación de dominios.

Imaginemos un sistema distribuido con dos tipos de mensajes: TreeRoot (que representa la raíz de un árbol de transparencia) y KeyRevoke (que indica la revocación de una clave). Si, por casualidad, estos mensajes tienen la misma estructura de campos, un atacante podría crear un mensaje KeyRevoke que se serialice exactamente igual que un TreeRoot. Luego, podría adjuntar la firma del TreeRoot al KeyRevoke falso, engañando al verificador para que crea que el firmante firmó el KeyRevoke cuando en realidad firmó el TreeRoot. Este tipo de ataque ha sido exitoso en diversos contextos, incluyendo Bitcoin, DEXs en Ethereum, TLS, JWTs y AWS.

La solución propuesta por FOKS, a través de su compilador Snowpack, introduce 'separadores de dominio' aleatorios e inmutables directamente en la definición de la estructura de datos (IDL). Por ejemplo, un TreeRoot podría tener un separador de dominio @0x92880d38b74de9fb. El compilador genera código que concatena este separador de dominio con la serialización del objeto antes de la firma o encriptación. El separador no se incluye en los datos serializados finales para ahorrar espacio, pero es conocido tanto por el firmante como por el verificador. Esto asegura que ambos estén de acuerdo sobre el tipo de datos que están procesando, previniendo ataques de sustitución.

Además de la separación de dominios, Snowpack también se enfoca en proporcionar codificaciones canónicas, a diferencia de sistemas como Protobufs que no ofrecen esta garantía. Snowpack codifica las estructuras como arrays posicionales similares a JSON, lo que evita confusiones entre cadenas y datos binarios.

La implementación de Snowpack incluye mecanismos para garantizar la unicidad de los separadores de dominio, previniendo errores de copia-pega o generación secuencial. Aunque los desarrolladores pueden cambiar el nombre de una estructura, se recomienda mantener el separador de dominio fijo para asegurar la compatibilidad hacia atrás. En resumen, Snowpack ofrece una solución sistemática y efectiva para un problema crítico en la seguridad de sistemas distribuidos, combinando separación de dominios, codificaciones canónicas y una fuerte tipificación.