Verificación
La cadena de integridad, especificada
Todo lo necesario para comprobar un registro sin usar nuestra aplicación: campos, orden, codificación y resumen, con vectores de prueba que cualquier implementación debe reproducir.
Resumen
Qué se calcula
Cada asiento lleva el resumen del anterior y el suyo. El suyo es el SHA-256, en hexadecimal minúscula, del resumen previo, una barra vertical y el JSON canónico de todos sus campos salvo cinco de control:
datos = asiento sin id, secuencia, hashPrevio, hash ni registradoEn
hash = SHA-256( hashPrevio + "|" + canónico(datos) )El primer asiento de una empresa tiene como resumen previo 64 ceros. Para cada asiento, por orden de secuencia, se comprueba que la secuencia sube de uno en uno, que su resumen previo es el del anterior, que su resumen coincide con el recalculado y que la hora de registro no retrocede. Se informan todas las roturas, no solo la primera.
El JSON canónico no lleva espacios, ordena las claves por unidades de código UTF-16, escapa solo comillas, barra invertida y caracteres de control, y escribe los números comoNumber::toString de ECMAScript (1.0 es 1, 1e+21,1e-7). Esos detalles son los que hacen fallar una implementación nueva, y por eso hay vectores específicos para ellos.
Encima de la cadena hay tres pruebas más: un sello diario encadenado, un sello diario firmado con Ed25519 y un recibo firmado por asiento (JWS, RFC 7515). Y un paquete pericial, un único fichero con todo ello. La especificación completa, con los códigos de problema de cada comprobación, está en ESPECIFICACION-INTEGRIDAD.md.
Implementaciones
Tres programas que coinciden
Además de la del motor de la aplicación, hay dos implementaciones independientes, escritas a partir de la especificación y no a partir del motor. Una prueba automática exige que las cuatro den el mismo veredicto y los mismos códigos en todos los vectores.
verificar.mjs: un fichero de Node.js 20 o superior, sin dependencias ni red, que también se ejecuta en el navegador (es el de /verificacion).verificar.py: referencia en Python 3.9 o superior, solo biblioteca estándar, con Ed25519 incluido. Pensada para contrastar la especificación desde otro lenguaje, no como sustituto de una librería criptográfica auditada.
node verificar.mjs paquete.json
python verificar.py paquete.jsonVectores
Casos de prueba oficiales
Cada fichero se descarga tal cual. La salida esperada es 0 si todo cuadra y 1 si hay problemas; los códigos son un conjunto, sin repetir. El índice completo, con el JWKS de las claves de prueba, es esperado.json. Las claves de estos vectores son de prueba, fijas y públicas: no pertenecen a ningún servidor.
| Fichero | Qué contiene | Resultado esperado |
|---|---|---|
paquete-valido.json | Paquete íntegro: 6 asientos en 3 días, sellos, sellos firmados y 2 recibos | Válido |
paquete-asiento-alterado.json | Un asiento con la hora cambiada y las huellas del paquete rehechas | cadena_hash_no_corresponde |
paquete-asiento-borrado.json | Un asiento quitado | cadena_secuencia_incorrecta, cadena_discontinua y sellos firmados |
paquete-asiento-insertado.json | Un asiento falso metido entre dos | cadena_secuencia_incorrecta, cadena_discontinua y sellos firmados |
paquete-cadena-reescrita.json | Asiento alterado con la cadena recalculada: cuadra por sí sola | recibo_no_coincide, cierre_no_corresponde, sello_firmado_huella |
paquete-sello-falso.json | Sello diario firmado por otra clave | sello_firmado_invalido |
paquete-un-byte.json | Un solo byte cambiado en el fichero | huella_global, huella_parte |
cadena-valida.json | Lista de asientos íntegra | Válida |
cadena-alterada.json | Lista con un asiento alterado | cadena_hash_no_corresponde |
cadena-con-hueco.json | Lista con un asiento borrado | cadena_secuencia_incorrecta, cadena_discontinua |
cadena-insertada.json | Lista con un asiento falso insertado | cadena_secuencia_incorrecta, cadena_discontinua |
recibo-valido.txt | Recibo firmado (con jwks.json y asiento-del-recibo.json) | Válido |
recibo-falso.txt | Recibo firmado por otra clave | recibo_invalido |
canonizacion.json | Casos de canonización y de resumen de asiento | Reproducir el resultado |
Límites
Qué no acredita
- Prueba integridad, no autoría ni que los hechos sean ciertos: un fichaje falso desde el origen queda igual de encadenado.
- Los recibos y los sellos firmados llevan una clave de El Registro de Jornada: son sellos de integridad, no firma electrónica cualificada ni sello cualificado de tiempo.
- Sin el JWKS publicado, las firmas solo se contrastan con las claves que lleva el propio paquete.
- No sustituye a un perito.
Estamos terminando la aplicación.
Déjanos tu correo y entrarás antes que el resto, con los catorce días de prueba desde el primer día. Preferimos decirte que aún no está a venderte una prueba que hoy no podríamos darte.