Resumen

  • Un Internet-Draft individual publicado el 5 de septiembre de 2026 tomó un objeto COSE_Sign1 de 165 octetos y combinó seis libertades binarias de codificación CBOR.
  • Las 64 combinaciones generaron 64 secuencias y 64 valores de data-hash, sin colisiones; la Sig_structure fue idéntica, de 109 octetos, y la firma se verificó en todos los casos.
  • El decodificador no rechazó ninguna entrada. En 31 casos, decodificar y volver a codificar devolvió los bytes de la representación inicial sin avisar del cambio.
  • La ejecución independiente del script publicado reprodujo el hash del objeto A, las 64 huellas, los cero rechazos y las 31 normalizaciones.
  • No hay evidencia de ataque, incidente desplegado ni decisión de la IETF. El hallazgo delimita una obligación operativa: nombrar y conservar la preimagen exacta del identificador.

Verificar contenido no equivale a identificar bytes

Un COSE_Sign1 contiene más estructura de la que observa su firma. Conforme a RFC 9052, la verificación reconstruye una Sig_structure con el contexto previsto, la cabecera protegida, los datos autenticados externos y la carga. La forma concreta del contenedor CBOR exterior puede cambiar sin modificar esos valores.

El data-hash que analiza el borrador de medición mira precisamente esa forma exterior: es el resumen de la secuencia completa de octetos transmitida. Por eso responde a otra pregunta. La firma acredita la materia cubierta; el hash permite distinguir, recuperar y comparar una representación exacta.

Ambas respuestas pueden ser correctas a la vez. Dos receptores pueden validar la misma firma y discrepar sobre el identificador si uno conserva lo que recibió y el otro conserva lo que su biblioteca volvió a emitir. La gobernanza comienza al declarar cuál de esas representaciones tiene autoridad.

Un experimento con seis ejes

El punto de partida A mide 165 octetos. Sin cambiar ningún valor del objeto, el experimento alterna la presencia de la etiqueta CBOR 18, la longitud definida o indefinida del array exterior y la misma elección en el mapa de cabeceras no protegidas. También alterna entre cadenas enteras o fragmentadas para la cabecera protegida, la carga y la firma.

Seis decisiones de dos opciones producen 64 combinaciones. El artefacto publicado enumera 64 secuencias de entre 164 y 170 octetos. Cada una tiene un SHA-256 diferente; no se produjo una sola colisión. Al mismo tiempo, todas comparten una única Sig_structure de 109 octetos y, por tanto, la misma firma válida.

La cifra no pretende agotar CBOR. No se ensayaron anchuras alternativas para enteros ni órdenes distintos de claves en mapas. RFC 8949 explica por qué el espacio de representación es más amplio. Una norma que enumere solo los encuadres ya encontrados no puede demostrar que controla los que faltan.

Treinta y un cambios sin error

El decodificador usado por el autor aceptó las 64 entradas. Para 31 de ellas, el ciclo leer–escribir produjo exactamente A, aunque los bytes recibidos fueran otros. La aplicación obtiene un objeto utilizable y ningún código de error, pero deja de tener la preimagen original.

Ese comportamiento permite una secuencia difícil de auditar. El servicio recibe B y publica hash(B). Después guarda el valor decodificado o su versión A. Cuando un cliente vuelve con el identificador, el servicio puede validar la firma y mostrar un objeto equivalente, pero ya no puede demostrar hash(B) con su copia. La clave de búsqueda y la prueba almacenada han tomado caminos distintos.

Esto no acusa a un parser. La reemisión consistente puede ser una propiedad legítima de una biblioteca. Tampoco sabemos si algún servicio de transparencia real descarta sus bytes de entrada. La medición solo demuestra que «el parser lo aceptó» no certifica «guardamos lo que identificamos».

La réplica independiente conserva sus límites

El vector inicial, los resultados y el script son públicos. Ante un fallo del enlace raw de GitHub, obtuve el mismo archivo mediante la API Contents y lo ejecuté en un directorio temporal con copias verificadas de los dos JSON. El resultado reconstruyó A con SHA-256 8595e4a4c8b93e7b1b7b798dc302a2b7d2890021f7eff372d79b32f78867e4ac; volvió a encontrar 64 hashes, cero rechazos y 31 normalizaciones.

La réplica usó cbor2 5.7.1. El borrador registra 6.1.3, CPython 3.13 y macOS arm64. Coincidir con otra versión es una comprobación valiosa, no una prueba universal de interoperabilidad. Mucho menos concede autoridad institucional al documento.

El Datatracker lo clasifica como Internet-Draft individual sin respaldo de la IETF, vía RFC, Area Director responsable ni posición formal. El propio texto dice que no especifica nada. No se falsificó una firma, no hubo colisión, no se rompió SHA-256 y no se midió un despliegue.

La redacción exacta aún está en disputa

El debate alcanzó al perfil CCF para recibos COSE, que estaba en Last Call de la IETF al cierre de la investigación. En un mensaje del 5 de septiembre, Nicholas Templeman apoyó avanzar el perfil y sugirió que data-hash cubriera los octetos tal como fueron registrados, no una serialización posterior. Definió su comentario como no bloqueante.

La precisión importa: es la propuesta de un participante, no texto aprobado ni consenso. El borrador SCRAPI y el perfil CCF siguen siendo trabajos del grupo en evolución. RFC 9943 sí es la arquitectura SCITT publicada, pero distingue roles generales y no resuelve por sí solo esta preimagen.

Además, la revisión 02 del Internet-Draft individual Canonical Payload Binding ya registra conceptualmente as-transmitted: no aplicar canonicalización y tomar la secuencia exacta como preimagen. Las opciones jcs-n y cde-n figuran como Withdrawn. El nuevo experimento cuantifica un problema que tenía una respuesta propuesta; no convierte esa respuesta en obligación.