Verificación de evidencias sin conexión
Un paquete de evidencias es un archivo ZIP exportado desde el panel. Contiene los registros de consentimiento, los archivos necesarios para comprobarlos y los scripts que ejecutan las comprobaciones. Nada de lo descrito en esta página necesita una conexión de red ni un servidor de HashEntry.
Esta página indica qué acredita cada comprobación. Ninguna comprobación por sí sola hace que un registro sea “a prueba de manipulaciones”; en conjunto, permiten que un tercero detecte cambios y vincule un registro a un momento en el tiempo.
Qué contiene un paquete
Sección titulada «Qué contiene un paquete»| Archivo | Contenido |
|---|---|
consent_data.json | Los registros exportados. Cada registro tiene un bloque proof con la carga útil sobre la que se calculó el hash. |
manifest.json, metadata.json | Identificador del paquete, versión de la especificación, número de registros, package_hash. |
checksums.sha256 | SHA-256 de cada archivo del paquete. |
timestamps.tsv + *.tsr | Tokens de sello de tiempo RFC 3161 (tsa_consent_<id>.tsr, tsa_epoch_<id>.tsr, package.tsr) y lo que cubre cada uno. |
merkle_proofs.tsv | Pruebas de inclusión Merkle (para los registros sellados en el tiempo por lotes). |
verify.sh, verify.ps1, README_*.txt, proof_verification.txt | Scripts de verificación e instrucciones. |
Los paquetes son de dos tipos: sin firmar (solo sumas de comprobación) y firmados (el hash del paquete lleva además un sello de tiempo RFC 3161, package.tsr).
Comprobación rápida
Sección titulada «Comprobación rápida»# Linux / macOSchmod +x verify.sh && ./verify.sh# Windowspowershell -ExecutionPolicy Bypass -File .\verify.ps1Los scripts comprueban las sumas de comprobación de los archivos, el manifiesto, los sellos de tiempo y las pruebas Merkle. No recalculan el hash de prueba, porque para ello se necesita la clave secreta del responsable del tratamiento (véase más abajo).
1. Integridad de los archivos
Sección titulada «1. Integridad de los archivos»sha256sum -c checksums.sha256 # macOS: shasum -a 256 -c checksums.sha256sha256sum consent_data.json # debe ser igual a "package_hash" en manifest.jsonEsto muestra que los archivos son los enumerados en el paquete. Por sí solo no muestra quién creó el paquete ni cuándo: cualquiera puede recalcular las sumas de comprobación después de modificar un archivo. Para eso sirve el sello de tiempo de un paquete firmado.
2. El hash de prueba
Sección titulada «2. El hash de prueba»Cada registro tiene un proof_hash. Para los registros actuales (hash_version: 2):
proof_hash = HMAC-SHA256( clave = clave secreta del tenant, mensaje = canonical_json(payload) ) → hexadecimal en minúsculasLa carga útil tiene siempre estas once claves (un valor ausente es null):
v (= 2), site_id, document_hash, consent_type, decision, categories, timestamp,pii_digest, signer_digest, custom_document_hash, signature_hashtimestampestá en UTC con precisión de segundos,YYYY-MM-DDTHH:MM:SS+00:00, y es igual a la hora de creación del registro.- Los datos personales no entran directamente en el hash. Entran a través de resúmenes (digests) con sal:
pii_digest = SHA-256( pii_salt || canonical_json({ip_address, user_agent, visitor_id}) ), ysigner_digest = SHA-256( pii_salt || canonical_json(campos de evidencia del firmante) )(onullcuando no hay firma ni declaración de identidad). Cuando un registro se anonimiza, los campos personales y la sal se eliminan, pero los resúmenes permanecen, de modo que el hash de prueba puede seguir recalculándose mientras que los resúmenes ya no pueden vincularse a una dirección IP o de correo electrónico.
JSON canónico (HashEntry Canonical JSON v2; no es RFC 8785):
- UTF-8, sin espacios en blanco entre tokens.
- Claves de objeto ordenadas por orden de bytes UTF-8, en todos los niveles.
- Se conserva el orden de los arrays.
- Un objeto vacío y un array vacío se escriben ambos como
[]. - En las cadenas solo se escapan
",\y los caracteres de control U+0000–U+001F;/y los caracteres no ASCII no se escapan. - Los números son únicamente enteros.
true,false,nullen minúsculas.
Quién puede comprobarlo. El hash de prueba es un hash con clave. Recalcularlo requiere la clave secreta del tenant, por lo que puede comprobarlo el responsable del tratamiento (que posee la clave) o un perito al que el responsable entregue la clave. Sin la clave, un tercero no puede recalcularlo, y tampoco lo necesita: las comprobaciones de sello de tiempo y Merkle descritas más abajo operan sobre el propio valor proof_hash y muestran que ese valor existía en el momento indicado.
# Con la clave: recalcular el hash de prueba de un registro (carga útil canónica en payload.json, sin salto de línea final)openssl dgst -sha256 -hmac "$TENANT_SECRET_KEY" payload.jsonLos registros heredados (hash_version: 1) utilizan SHA-256( json(payload con las claves de nivel superior ordenadas) || clave ) y contienen datos personales directamente en la carga útil.
3. Sellos de tiempo RFC 3161
Sección titulada «3. Sellos de tiempo RFC 3161»timestamps.tsv tiene una fila por token:
<file.tsr> <kind> <stamped data> <provider> <level at issuance>Los datos sellados (<stamped data>) son una cadena hexadecimal en minúsculas: el proof_hash de un registro, una raíz Merkle o el package_hash. La autoridad de sellado de tiempo (TSA) firmó el SHA-256 de los caracteres ASCII de esa cadena, sin salto de línea final:
printf '%s' "<stamped data>" > data.txtopenssl ts -verify -data data.txt -in <file.tsr> -CAfile <tsa_root.pem>- El certificado raíz de la TSA no está en el paquete. Obténgalo de la propia autoridad de sellado de tiempo; una raíz suministrada por la parte cuyos datos se están comprobando no probaría nada.
- Los tokens de algunas autoridades no superan la comprobación
ESSCertIDdeopenssl ts -verify. En ese caso, verifique la firma y la cadena en dos pasos:
openssl ts -reply -in <file.tsr> -token_out -out token.deropenssl cms -verify -inform DER -in token.der -CAfile <tsa_root.pem> \ -purpose timestampsign -binary -out tstinfo.deropenssl ts -reply -in <file.tsr> -text # compare "Message data" con el SHA-256 de los datos selladosUna fila cuyo nivel es simulated es un sello de tiempo de prueba: no tiene archivo .tsr ni valor probatorio.
Un token válido muestra que el valor sellado existía, a más tardar, en el momento que figura en el token, según esa autoridad de sellado de tiempo. Que los sellos de tiempo de una autoridad determinada gocen de una presunción legal (por ejemplo, los sellos cualificados de tiempo electrónicos conforme a eIDAS, o los sellos de tiempo de un proveedor autorizado conforme a la legislación turca) depende de la autoridad y de la jurisdicción.
4. Pruebas de inclusión Merkle
Sección titulada «4. Pruebas de inclusión Merkle»Cuando los registros se sellan en el tiempo por lotes, un único token cubre la raíz Merkle de un lote y cada registro recibe una prueba de inclusión. merkle_proofs.tsv:
<consent_id> <leaf> <index> <leaf_count> <root> <epoch.tsr> <path>El árbol es el esquema Merkle binario SHA-256 propio de HashEntry. No es el árbol de RFC 6962 (Certificate Transparency), y las herramientas de RFC 6962 no lo verificarán:
- hoja = el
proof_hashdel registro (64 caracteres hexadecimales en minúsculas), sin ningún hash adicional; - nodo = SHA-256 sobre los 128 caracteres ASCII
hex(left) || hex(right): las cadenas hexadecimales, no los bytes sin procesar; - una capa con un número impar de nodos duplica su último nodo;
- no hay prefijo de separación de dominio entre hojas y nodos.
Para verificar una ruta, comience con cur = leaf y aplique cada paso:
L:<h> → cur = sha256(<h> || cur)R:<h> → cur = sha256(cur || <h>)# un paso, p. ej. "R:<h>"cur=$(printf '%s%s' "$cur" "$h" | sha256sum | cut -d' ' -f1)El resultado debe ser igual a <root>. Compruebe también que 0 <= index < leaf_count y que el número de pasos es igual a la profundidad del árbol para leaf_count: la regla de duplicación no vincula el tamaño del árbol a la raíz, por lo que estos valores forman parte de la prueba. Por último, verifique <epoch.tsr> frente a <root> como en la sección 3: eso es lo que prueba cuándo existía la raíz y, por tanto, el hash de prueba del registro.
Qué acreditan las comprobaciones en conjunto
Sección titulada «Qué acreditan las comprobaciones en conjunto»| Comprobación | Acredita |
|---|---|
| Sumas de comprobación | Los archivos del paquete son coherentes entre sí. |
| Hash de prueba (con la clave) | El contenido del registro coincide con el hash calculado cuando se escribió. |
| Token RFC 3161 | El valor sellado existía, a más tardar, en el momento del token, según esa autoridad. |
| Prueba Merkle + token de época | El hash de prueba del registro formaba parte de un lote cuya raíz existía en ese momento. |
Lo que no acreditan: quién era la persona (véase identity_assurance en Aprobación y firma de documentos), ni que el registro se creara correctamente en primer lugar. Los registros sin token de sello de tiempo se apoyan únicamente en el hash de prueba y, por tanto, en el secreto de la clave.