Hash Service - SHA3-256 Probatoire¶
Vue d'ensemble¶
Le HashService est le service central de calcul d'empreintes cryptographiques pour les documents probatoires. Il utilise SHA3-256 (NIST FIPS 202) pour garantir l'intégrité des documents chiffrés sans jamais les déchiffrer.
Implémentation¶
Fichier source¶
src/modules/crypto/hash.service.ts
Méthodes principales¶
hashDocument(file: Buffer): string¶
Calcule le hash SHA3-256 d'un document chiffré.
Paramètres : - file : Buffer du fichier chiffré (doc.enc)
Retour : - Hash hexadécimal (64 caractères)
Exemple :
const encryptedFile = Buffer.from(...);
const hash = hashService.hashDocument(encryptedFile);
// Returns: "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"
Exceptions : - BadRequestException : Fichier vide ou invalide
hashDocumentStream(stream: Readable): Promise<string>¶
Hash un fichier en mode streaming (pour fichiers > 10MB).
Paramètres : - stream : Stream du fichier chiffré
Retour : - Promise
Exemple :
const fileStream = fs.createReadStream('document.enc');
const hash = await hashService.hashDocumentStream(fileStream);
Avantages : - Pas de surcharge mémoire - Traitement par chunks - Performance optimale pour gros fichiers
verify(data: Buffer, expectedHash: string): boolean¶
Vérifie l'intégrité d'un document.
Paramètres : - data : Données à vérifier - expectedHash : Hash attendu (64 caractères)
Retour : - true si le hash correspond - false sinon
Exemple :
const isValid = hashService.verify(fileBuffer, storedHash);
if (isValid) {
console.log('Intégrité préservée ✓');
}
isValidHashFormat(hash: string): boolean¶
Valide le format d'un hash SHA3-256.
Exemple :
const valid = hashService.isValidHashFormat('3a985da7...');
// Returns: true si format correct (64 hex chars)
Propriétés cryptographiques¶
SHA3-256 (Keccak)¶
| Propriété | Valeur |
|---|---|
| Algorithme | SHA3-256 (Keccak) |
| Standard | NIST FIPS 202 |
| Taille sortie | 256 bits (32 bytes) |
| Format | Hexadécimal (64 caractères) |
| Résistance collision | 2^128 opérations |
| Résistance pré-image | 2^256 opérations |
| Résistance quantique | ✅ Oui |
| Déterministe | ✅ Oui |
Avantages SHA3-256 vs SHA2-256¶
- Résistance quantique : SHA3 résiste mieux aux attaques quantiques
- Construction différente : Éponge Keccak vs Merkle-Damgård
- Sécurité prouvée : Standard NIST depuis 2015
- Pas de vulnérabilités connues : Aucune attaque pratique
Tests NIST¶
Le service est testé avec les vecteurs officiels NIST FIPS 202.
Vecteur #1 : "abc"¶
Vecteur #2 : "abcdbcdecdef..."¶
Input: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
Output: "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376"
Vecteur #3 : 1 million de "a"¶
Résultats : ✅ 4/4 vecteurs passent
Performance¶
Benchmark¶
| Taille fichier | Temps mesuré | Exigence | Status |
|---|---|---|---|
| 1 MB | 13ms | < 50ms | ✅ |
| 10 MB | 124ms | < 500ms | ✅ |
| 100 MB | ~1.2s | < 5s | ✅ |
Hardware : Node.js 20 sur processeur moderne
Optimisations¶
- Buffer natif : Utilisation directe de
js-sha3 - Streaming : Pour fichiers > 10MB
- Pas d'allocation inutile : Traitement en place
Utilisation dans le flux probatoire¶
1. Upload document¶
// Dans DocumentsController
async uploadDocument(file: Buffer) {
// Calcul hash probatoire
const hashDoc = this.hashService.hashDocument(file);
// Stockage avec hash
const document = await this.documentsService.create({
name: 'contract.pdf',
hashDoc, // Hash probatoire
size: file.length,
// ...
});
return { doc_id: document.id, hash_doc: hashDoc };
}
2. Vérification intégrité¶
// Dans DocumentsService
async verifyIntegrity(id: string, fileBuffer: Buffer): Promise<boolean> {
const document = await this.findOne(id);
const computedHash = this.hashService.hashDocument(fileBuffer);
return document.hashDoc === computedHash;
}
3. Ancrage blockchain¶
// Dans BlockchainService
async anchorDocuments(docIds: string[]) {
// Récupération des hash probatoires
const hashes = await this.documentsService.getHashes(docIds);
// Construction Merkle Tree
const { root } = this.merkleService.buildMerkleTree(hashes);
// Ancrage root sur blockchain
const txId = await this.anchorService.anchorRoot(root);
return { merkle_root: root, transaction_id: txId };
}
Sécurité¶
✅ Bonnes pratiques¶
- Hash sur doc.enc (chiffré) : Jamais sur le clair
- Validation stricte : Rejette fichiers vides/invalides
- Pas de logs sensibles : Hash partiel uniquement (10 premiers chars)
- Index unique : Détection automatique des doublons
- Format validé : Regex pour 64 caractères hexadécimaux
❌ À éviter¶
- Ne jamais hasher le document en clair
- Ne jamais logger le hash complet
- Ne jamais stocker le hash sans validation
- Ne jamais utiliser MD5 ou SHA1 (obsolètes)
Conformité¶
Standards respectés¶
- NIST FIPS 202 : SHA3-256 standard officiel
- NF Z42-013 : Archivage électronique (hash probatoire)
- ISO 14641 : Intégrité des documents archivés
- ANSSI : Recommandations cryptographiques
Valeur probatoire¶
Le hash SHA3-256 constitue une preuve d'intégrité : - Opposable juridiquement : Standard reconnu - Infalsifiable : Résistance collision 2^128 - Vérifiable sans déchiffrement : Principe Zero-Knowledge - Ancrable blockchain : Via Merkle Tree
Références¶
- NIST FIPS 202
- Keccak Team
- js-sha3 Library
src/modules/crypto/hash.service.spec.ts
Support¶
Pour toute question sur le HashService : - Email : crypto@probatiovault.com - GitLab Issues : Créer une issue