Vérifier une preuve hors ligne
Un paquet de preuves est un fichier ZIP exporté depuis le tableau de bord. Il contient les enregistrements de consentement, les fichiers nécessaires pour les contrôler et des scripts qui exécutent les contrôles. Rien sur cette page ne nécessite de connexion réseau ni de serveur HashEntry.
Cette page indique ce que chaque contrôle établit. Aucun contrôle ne rend à lui seul un enregistrement « infalsifiable » ; ensemble, ils permettent à un tiers de détecter des modifications et de rattacher un enregistrement à un moment dans le temps.
Contenu d’un paquet
Section intitulée « Contenu d’un paquet »| Fichier | Contenu |
|---|---|
consent_data.json | Les enregistrements exportés. Chaque enregistrement comporte un bloc proof avec le payload haché. |
manifest.json, metadata.json | Identifiant du paquet, version de la spécification, nombre d’enregistrements, package_hash. |
checksums.sha256 | SHA-256 de chaque fichier du paquet. |
timestamps.tsv + *.tsr | Jetons d’horodatage RFC 3161 (tsa_consent_<id>.tsr, tsa_epoch_<id>.tsr, package.tsr) et ce que chacun couvre. |
merkle_proofs.tsv | Preuves d’inclusion Merkle (pour les enregistrements horodatés par lots). |
verify.sh, verify.ps1, README_*.txt, proof_verification.txt | Scripts de vérification et instructions. |
Les paquets existent en deux types : non signé (sommes de contrôle uniquement) et signé (le hash du paquet porte en plus un horodatage RFC 3161, package.tsr).
Contrôle rapide
Section intitulée « Contrôle rapide »# Linux / macOSchmod +x verify.sh && ./verify.sh# Windowspowershell -ExecutionPolicy Bypass -File .\verify.ps1Les scripts contrôlent les sommes de contrôle des fichiers, le manifeste, les horodatages et les preuves Merkle. Ils ne recalculent pas le hash de preuve, car cela nécessite la clé secrète du responsable du traitement (voir ci-dessous).
1. Intégrité des fichiers
Section intitulée « 1. Intégrité des fichiers »sha256sum -c checksums.sha256 # macOS : shasum -a 256 -c checksums.sha256sha256sum consent_data.json # doit être égal à "package_hash" dans manifest.jsonCela montre que les fichiers sont bien ceux listés dans le paquet. À lui seul, cela ne montre pas qui a créé le paquet ni quand — n’importe qui peut recalculer les sommes de contrôle après avoir modifié un fichier. C’est à cela que sert l’horodatage d’un paquet signé.
2. Le hash de preuve
Section intitulée « 2. Le hash de preuve »Chaque enregistrement possède un proof_hash. Pour les enregistrements actuels (hash_version: 2) :
proof_hash = HMAC-SHA256( key = clé secrète du tenant, message = canonical_json(payload) ) → hex en minusculesLe payload comporte toujours ces onze clés (une valeur manquante vaut null) :
v (= 2), site_id, document_hash, consent_type, decision, categories, timestamp,pii_digest, signer_digest, custom_document_hash, signature_hashtimestampest en UTC avec une précision à la seconde,YYYY-MM-DDTHH:MM:SS+00:00, et est égal à l’heure de création de l’enregistrement.- Les données personnelles n’entrent pas directement dans le hash. Elles y entrent par l’intermédiaire de condensats salés :
pii_digest = SHA-256( pii_salt || canonical_json({ip_address, user_agent, visitor_id}) ), etsigner_digest = SHA-256( pii_salt || canonical_json(champs de preuve du signataire) )(ounulllorsqu’il n’y a ni signature ni déclaration d’identité). Lorsqu’un enregistrement est anonymisé, les champs personnels et le sel sont supprimés mais les condensats demeurent ; le hash de preuve peut donc toujours être recalculé, tandis que les condensats ne peuvent plus être reliés à une adresse IP ou à une adresse e-mail.
JSON canonique (HashEntry Canonical JSON v2 — ce n’est pas la RFC 8785) :
- UTF-8, aucun espace blanc entre les tokens.
- Clés d’objet triées selon l’ordre des octets UTF-8, à chaque niveau.
- L’ordre des tableaux est conservé.
- Un objet vide et un tableau vide s’écrivent tous deux
[]. - Dans les chaînes, seuls
",\et les caractères de contrôle U+0000–U+001F sont échappés ;/et les caractères non ASCII ne le sont pas. - Les nombres sont uniquement des entiers.
true,false,nullen minuscules.
Qui peut le contrôler. Le hash de preuve est un hash à clé. Le recalculer nécessite la clé secrète du tenant ; il peut donc être contrôlé par le responsable du traitement (qui détient la clé) ou par un expert auquel le responsable du traitement remet la clé. Sans la clé, un tiers ne peut pas le recalculer — et n’en a pas besoin : les contrôles d’horodatage et Merkle ci-dessous portent sur la valeur proof_hash elle-même et montrent que cette valeur existait à l’heure indiquée.
# Avec la clé : recalculer le hash de preuve d'un enregistrement (payload canonique dans payload.json, sans saut de ligne final)openssl dgst -sha256 -hmac "$TENANT_SECRET_KEY" payload.jsonLes anciens enregistrements (hash_version: 1) utilisent SHA-256( json(payload avec les clés de premier niveau triées) || key ) et contiennent des données personnelles directement dans le payload.
3. Horodatages RFC 3161
Section intitulée « 3. Horodatages RFC 3161 »timestamps.tsv comporte une ligne par jeton :
<file.tsr> <kind> <stamped data> <provider> <level at issuance>La donnée horodatée (<stamped data>) est une chaîne hexadécimale en minuscules : le proof_hash d’un enregistrement, une racine Merkle ou le package_hash. L’autorité d’horodatage (TSA) a signé le SHA-256 des caractères ASCII de cette chaîne, sans saut de ligne final :
printf '%s' "<stamped data>" > data.txtopenssl ts -verify -data data.txt -in <file.tsr> -CAfile <tsa_root.pem>- Le certificat racine de la TSA ne se trouve pas dans le paquet. Obtenez-le auprès de l’autorité d’horodatage elle-même ; une racine fournie par la partie dont vous contrôlez les données ne prouverait rien.
- Les jetons de certaines autorités échouent au contrôle
ESSCertIDdeopenssl ts -verify. Vérifiez alors la signature et la chaîne en deux étapes :
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 # comparez "Message data" avec le SHA-256 de la donnée horodatéeUne ligne dont le niveau est simulated est un horodatage de test : elle n’a pas de fichier .tsr et aucune valeur probante.
Un jeton valide montre que la valeur horodatée existait au plus tard à l’heure figurant dans le jeton, selon cette autorité d’horodatage. Le fait que les horodatages d’une autorité donnée bénéficient d’une présomption légale (par exemple les horodatages qualifiés au titre d’eIDAS, ou les horodatages d’un prestataire autorisé en droit turc) dépend de l’autorité et de la juridiction.
4. Preuves d’inclusion Merkle
Section intitulée « 4. Preuves d’inclusion Merkle »Lorsque les enregistrements sont horodatés par lots, un seul jeton couvre la racine Merkle d’un lot et chaque enregistrement reçoit une preuve d’inclusion. merkle_proofs.tsv :
<consent_id> <leaf> <index> <leaf_count> <root> <epoch.tsr> <path>L’arbre est le schéma Merkle binaire SHA-256 propre à HashEntry. Ce n’est pas l’arbre de la RFC 6962 (Certificate Transparency), et les outils RFC 6962 ne le vérifieront pas :
- feuille = le
proof_hashde l’enregistrement (64 caractères hexadécimaux en minuscules), sans hachage supplémentaire ; - nœud = SHA-256 sur les 128 caractères ASCII
hex(left) || hex(right)— les chaînes hexadécimales, pas les octets bruts ; - une couche comportant un nombre impair de nœuds duplique son dernier nœud ;
- il n’y a pas de préfixe de séparation de domaine feuille/nœud.
Pour vérifier un chemin, commencez avec cur = leaf et appliquez chaque étape :
L:<h> → cur = sha256(<h> || cur)R:<h> → cur = sha256(cur || <h>)# une étape, p. ex. "R:<h>"cur=$(printf '%s%s' "$cur" "$h" | sha256sum | cut -d' ' -f1)Le résultat doit être égal à <root>. Vérifiez également que 0 <= index < leaf_count et que le nombre d’étapes est égal à la profondeur de l’arbre pour leaf_count — la règle de duplication ne lie pas la taille de l’arbre à la racine ; ces valeurs font donc partie de la preuve. Enfin, vérifiez <epoch.tsr> par rapport à <root> comme à la section 3 : c’est ce qui prouve à quel moment la racine, et donc le hash de preuve de l’enregistrement, existait.
Ce que les contrôles établissent ensemble
Section intitulée « Ce que les contrôles établissent ensemble »| Contrôle | Établit |
|---|---|
| Sommes de contrôle | Les fichiers du paquet sont cohérents entre eux. |
| Hash de preuve (avec la clé) | Le contenu de l’enregistrement correspond au hash calculé lors de son écriture. |
| Jeton RFC 3161 | La valeur horodatée existait au plus tard à l’heure du jeton, selon cette autorité. |
| Preuve Merkle + jeton d’epoch | Le hash de preuve de l’enregistrement faisait partie d’un lot dont la racine existait à ce moment-là. |
Ce qu’ils n’établissent pas : qui était la personne (voir identity_assurance dans Approbation de documents et signature), ni que l’enregistrement a été créé correctement à l’origine. Les enregistrements sans jeton d’horodatage reposent uniquement sur le hash de preuve, et donc sur le secret de la clé.