Détection de falsification dans les archives de documents : comment fonctionnent les chaînes de hachage
Vous ne pouvez pas vérifier qu’un document n’a pas été falsifié simplement en le regardant. Un PDF modifié est visuellement identique à l’original. Un fichier substitué porte le même nom. Une entrée de journal d’audit silencieusement éditée ne laisse aucune trace visible.
La détection de falsification nécessite un mécanisme qui fait que toute modification produit un artefact détectable, idéalement vérifiable par quelqu’un qui n’était pas présent lors de la création originale. Les chaînes de hachage sont l’un des mécanismes fondamentaux qui permettent d’atteindre cet objectif.
Ce que fait un hachage cryptographique
Une fonction de hachage cryptographique prend une entrée de longueur arbitraire et produit une sortie de longueur fixe (le condensé) avec deux propriétés critiques :
- Déterminisme : la même entrée produit toujours la même sortie
- Effet avalanche : tout changement dans l’entrée, même un seul bit, produit une sortie complètement différente
SHA-256 produit un condensé de 256 bits (32 octets). Pour toute entrée pratique, il est computationnellement infaisable de :
- Trouver deux entrées différentes qui produisent la même sortie (résistance aux collisions)
- Reconstruire l’entrée à partir de la sortie (résistance aux préimages)
- Produire une sortie spécifique sans connaître l’entrée (résistance aux secondes préimages)
Ces propriétés signifient qu’un hachage SHA-256 est une empreinte fiable d’un document. Si le hachage correspond, le document est identique à ce qui a été haché. Si le hachage ne correspond pas, quelque chose a changé.
var hash = SHA256.HashData(File.ReadAllBytes("invoice.pdf"));
Console.WriteLine(Convert.ToHexString(hash));
// A3F8C2...1B7D (64 hex chars, always the same for this file, always different if file changes)
Pourquoi un seul hachage ne suffit pas
Hacher un document vous donne une empreinte à un moment donné. Mais qui stocke cette empreinte, et qu’est-ce qui empêche quelqu’un de remplacer à la fois le document et le hachage stocké ?
Si vous stockez le hachage dans le même système que le document, et que vous contrôlez ce système, un attaquant déterminé (ou un acteur interne couvrant ses traces) peut remplacer les deux. Le hachage correspond toujours au nouveau document. La falsification est indétectable.
C’est pourquoi la détection de falsification nécessite une ancre externe : un hachage stocké quelque part que le dépositaire ne peut pas modifier unilatéralement. Un horodatage RFC 3161 est le mécanisme standard : il intègre le hachage du document dans un jeton signé par une TSA tierce. Le dépositaire ne peut pas modifier le jeton sans la clé privée de la TSA.
Ce qu’une chaîne de hachage ajoute
Une chaîne de hachage étend cela à une séquence d’événements. Au lieu de hacher uniquement le document, vous hachez chaque entrée d’audit et incluez le hachage de l’entrée précédente dans l’entrée actuelle.
Hash(Entry N) = SHA256( EventData(N) + Hash(Entry N-1) )
Cela crée une chaîne où chaque entrée s’engage sur toutes les entrées précédentes. Si vous modifiez l’entrée 3 dans une chaîne de 10 entrées, Hash(Entrée 3) change. Comme l’entrée 4 inclut Hash(Entrée 3), Hash(Entrée 4) change. Et ainsi de suite jusqu’à l’entrée 10.
Vous ne pouvez pas silencieusement modifier une entrée passée. La chaîne ne se validera pas.
Voici une implémentation minimale :
public sealed record AuditEntry(
string EventType,
string Actor,
DateTimeOffset Timestamp,
string DocumentHash,
string PreviousEntryHash)
{
public string ComputeHash()
{
var raw = $"{EventType}|{Actor}|{Timestamp:O}|{DocumentHash}|{PreviousEntryHash}";
return Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(raw)));
}
}
public static string AppendEntry(IList<AuditEntry> chain, string eventType,
string actor, byte[] documentBytes)
{
var previousHash = chain.Count == 0
? new string('0', 64)
: chain[^1].ComputeHash();
var docHash = Convert.ToHexString(SHA256.HashData(documentBytes));
var entry = new AuditEntry(eventType, actor, DateTimeOffset.UtcNow, docHash, previousHash);
chain.Add(entry);
return entry.ComputeHash();
}
public static bool VerifyChain(IList<AuditEntry> chain)
{
var expectedPrevious = new string('0', 64);
foreach (var entry in chain)
{
if (entry.PreviousEntryHash != expectedPrevious) return false;
expectedPrevious = entry.ComputeHash();
}
return true;
}
La vérification est O(n) et ne nécessite aucun appel externe. Quiconque dispose de la chaîne peut exécuter VerifyChain et confirmer qu’aucune entrée n’a été modifiée.
Ancrer la chaîne avec un horodatage
Une chaîne de hachage vérifiée prouve la cohérence interne : aucune entrée n’a été modifiée après la construction de la chaîne. Mais elle ne prouve pas quand la chaîne a été construite.
Si vous construisez une chaîne frauduleuse aujourd’hui et prétendez qu’elle représente des événements d’il y a trois ans, la chaîne elle-même se validera correctement. La chaîne de hachage n’a pas d’horloge.
C’est là que les horodatages RFC 3161 ancrent la chaîne dans le temps réel. À des moments clés de la chaîne (au minimum : à la finalisation de la chaîne ; idéalement à chaque événement significatif), demandez un horodatage à une TSA qualifiée. La TSA intègre le hachage de l’entrée actuelle dans un jeton signé avec un horodatage de confiance.
La chaîne dispose désormais d’une ancre externe. Vous ne pouvez pas antidater la chaîne au-delà du plus ancien horodatage, car le jeton de la TSA prouve que le hachage existait à ce moment, et l’horloge de la TSA fait autorité.
// After appending an entry, request a timestamp for the entry hash
var entryHash = AppendEntry(chain, "created", "api:tenant-1", documentBytes);
var entryHashBytes = Convert.FromHexString(entryHash);
var timestampToken = await RequestTimestampAsync(entryHashBytes, tsaUrl);
// Store the token alongside the chain entry
chain[^1] = chain[^1] with { TimestampToken = timestampToken };
Un auditeur vérifiant la chaîne peut :
- Vérifier que la chaîne de hachage est cohérente en interne (pas de modifications)
- Vérifier chaque jeton d’horodatage par rapport au certificat public de la TSA (pas d’antidatage)
- Vérifier le hachage du document dans chaque entrée par rapport au document actuel (pas de substitution)
Chaînes de hachage vs autres mécanismes d’intégrité
Journaux en ajout seul (tables de base de données sans DELETE) : Empêchent la suppression via des contrôles d’accès, mais ne sont que aussi fiables que le système de contrôle d’accès. Un administrateur de base de données peut les contourner. Les chaînes de hachage sont mathématiquement appliquées, pas par politique.
Signatures numériques sur des documents individuels : Une signature prouve qu’un document a été signé par une clé spécifique au moment de la signature. Elle n’enregistre pas ce qui est arrivé au document après. La chaîne de garde exige d’enregistrer les événements post-signature (transmission, conversion, archivage), pas seulement le moment de la signature.
Blockchain : Utilise les chaînes de hachage comme primitive centrale, mais ajoute un consensus distribué pour empêcher toute partie unique de réécrire l’histoire. Pour les archives de documents, une chaîne de hachage locale ancrée par des horodatages RFC 3161 externes fournit la même garantie de résistance à la falsification sans la complexité d’un réseau distribué. La distinction est importante : vous n’avez pas besoin d’un consensus entre inconnus pour prouver qu’un document n’a pas été modifié ; vous avez besoin d’une ancre externe que vous ne contrôlez pas.
Stockage WORM (Write Once Read Many) : Empêche toute modification au niveau de la couche de stockage. Le support ne peut physiquement pas être écrasé. C’est complémentaire aux chaînes de hachage, pas un remplacement. WORM prouve que les bits stockés n’ont pas changé. Une chaîne de hachage prouve quelle séquence d’événements a produit ces bits. Les deux ensemble fournissent des garanties plus fortes que l’un ou l’autre seul.
À quoi ressemble la vérification en pratique
Un flux de travail de vérification complet pour un document dans une archive à chaîne de hachage :
- Récupérer le document et la piste d’audit depuis l’archive
- Calculer le SHA-256 du document ; confirmer qu’il correspond au
documentHashdans la dernière entrée de la chaîne - Parcourir la chaîne à rebours, recalculer chaque
entryHashet confirmer qu’il correspond aupreviousEntryHashdans l’entrée suivante - Pour chaque entrée avec un jeton d’horodatage, vérifier le jeton par rapport au certificat de la TSA et confirmer que le hachage dans le jeton correspond au
entryHashcalculé - Confirmer que le hachage du document à l’étape 2 correspond au hachage du document dans l’entrée la plus ancienne couvrant la forme finale du document
Si les cinq étapes sont franchies, le document est vérifié comme non modifié depuis sa création, la piste d’audit enregistre précisément chaque étape de traitement, et les horodatages fournissent des ancres temporelles vérifiables de manière externe.
Cette vérification nécessite : le document, la piste d’audit, les jetons d’horodatage et les certificats publics de la TSA. Pas d’accès réseau. Pas de dépendance au fonctionnement des systèmes du dépositaire. Les preuves sont autonomes.
La détection de falsification comme infrastructure
La plupart des organisations n’implémentent pas de chaînes de hachage parce qu’elles leur semblent être une fonctionnalité avancée. Ce n’en est pas une. SHA-256 est disponible dans chaque runtime moderne. La construction de la chaîne représente quelques dizaines de lignes de code. L’avantage est que vous pouvez prouver l’intégrité d’un document à un tiers sceptique sans compter sur sa confiance envers votre organisation.
Pour les secteurs réglementés (finance, santé, assurance, secteur public), cette preuve n’est pas facultative. Pour toute organisation souhaitant présenter des documents numériques comme preuves dans un litige, c’est le niveau de base.
SealDoc implémente des pistes d’audit avec chaîne de hachage pour chaque document dans son pipeline. La chaîne est exportée dans le dossier de preuve légale et est vérifiable hors ligne. Pour les organisations qui ont besoin de construire leur propre infrastructure de preuve, l’API SealDoc expose la piste d’audit et les jetons d’horodatage sous forme de données structurées que vous pouvez intégrer dans vos propres flux de vérification.