Image de couverture : VeriFactu : les pièges du hash SHA-256 qui cassent la chaîne de factures
PHP & Frameworks

VeriFactu : les pièges du hash SHA-256 qui cassent la chaîne de factures

4 octobre 2026
6 min de lecture
69 vues
Sébastien Muler

Un calcul de hash qui ne tombe jamais juste du premier coup

Sur le papier, sceller une facture tient en deux gestes : assembler quelques champs dans une chaîne de caractères, puis appliquer SHA-256. En pratique, le résultat diffère presque toujours de celui attendu à la première tentative, et les erreurs les plus coûteuses n'apparaissent qu'en production. Voici les points de vigilance à connaître avant d'implémenter la "huella" exigée par le système espagnol VeriFactu.

Ce que demande la réglementation

En Espagne, les sociétés devront facturer avec un logiciel conforme à VeriFactu à partir du 1er janvier 2027, et les autres assujettis (indépendants compris) à partir du 1er juillet 2027. Chaque enregistrement de facturation reçoit une empreinte, la huella, calculée en SHA-256. Cette empreinte intègre celle de l'enregistrement précédent : les factures forment ainsi une chaîne, et toute modification a posteriori rompt les maillons suivants.

Pour un enregistrement d'émission, la chaîne à hacher est composée de 8 champs, toujours dans le même ordre, sous la forme nom=valeur séparés par & :

  • IDEmisorFactura
  • NumSerieFactura
  • FechaExpedicionFactura
  • TipoFactura
  • CuotaTotal
  • ImporteTotal
  • Huella (vide pour le premier enregistrement, sinon l'empreinte précédente)
  • FechaHoraHusoGenRegistro

La chaîne est encodée en UTF-8, hachée en SHA-256, puis le résultat est écrit en hexadécimal en majuscules. Un seul octet de différence produit une empreinte totalement différente, et c'est là que les ennuis commencent.

Les détails de format qui font diverger le hash

La fonction de hachage ne pardonne rien. Les écarts les plus fréquents viennent de la préparation de la chaîne, pas du calcul lui-même :

  • L'ordre des champs : il est fixe. Un tableau associatif dont l'ordre d'insertion varie suffit à produire une empreinte invalide.
  • Le format des valeurs : dates au format JJ-MM-AAAA, horodatage ISO 8601 avec fuseau horaire, montants avec un point décimal et le nombre de décimales attendu. Un 12.5 à la place de 12.50 change tout.
  • Les espaces parasites : une espace en début ou fin de valeur, souvent issue d'une saisie ou d'une base de données, fausse le résultat sans message d'erreur.
  • L'encodage : la chaîne doit être convertie en octets UTF-8. Les caractères accentués ou spéciaux dans un numéro de série posent problème si l'encodage du serveur est différent.
  • La casse du résultat : l'hexadécimal doit être en majuscules. Beaucoup de bibliothèques renvoient des minuscules par défaut.
  • Le champ Huella vide : pour le premier enregistrement, le champ est présent mais sans valeur (Huella=). L'omettre décale toute la chaîne.

Un exemple simple en PHP illustre la logique :

$chaine = implode('&', [
    'IDEmisorFactura=' . $emetteur,
    'NumSerieFactura=' . $numero,
    'FechaExpedicionFactura=' . $date,
    'TipoFactura=' . $type,
    'CuotaTotal=' . $cuota,
    'ImporteTotal=' . $total,
    'Huella=' . $huellePrecedente,
    'FechaHoraHusoGenRegistro=' . $horodatage,
]);

$huella = strtoupper(hash('sha256', $chaine));

Le plus sûr est de valider votre implémentation contre les exemples publiés par l'administration fiscale espagnole (AEAT), et d'en faire des tests unitaires de non-régression.

Le piège qui casse la chaîne : la concurrence

Les tests unitaires ne détectent pas le défaut le plus insidieux. Comme chaque empreinte dépend de la précédente, deux factures créées quasi simultanément peuvent lire la même empreinte précédente. Chacune se rattache alors au même maillon, et la chaîne se ramifie au lieu de rester linéaire. Le hash de chaque facture est correct pris isolément, mais la chaîne, elle, est invalide.

Ce type de défaut ne se manifeste que sous charge réelle, par exemple lors de deux paiements en ligne validés au même instant. Pour l'éviter, il faut sérialiser la génération des enregistrements :

  • exécuter la lecture de la dernière empreinte et l'écriture du nouvel enregistrement dans une seule transaction ;
  • verrouiller la ligne ou la table de référence pendant l'opération (SELECT ... FOR UPDATE sur une base relationnelle) ;
  • ajouter une contrainte d'unicité sur l'empreinte précédente, afin que la base rejette toute ramification plutôt que de l'accepter silencieusement ;
  • écrire un test de concurrence qui lance plusieurs créations en parallèle et vérifie que la chaîne reste linéaire.

La contrainte d'unicité est la meilleure assurance : même si le verrou est oublié ou contourné, l'erreur devient visible immédiatement au lieu de se découvrir lors d'un contrôle.

Une implémentation partielle ne suffit pas

Calculer correctement l'empreinte n'équivaut pas à être conforme. VeriFactu impose aussi la génération des enregistrements, leur transmission ou leur conservation selon le mode choisi, et d'autres exigences que le simple hachage ne couvre pas. L'auteur de l'article source le précise d'ailleurs lui-même au sujet de son plugin WooCommerce : le calcul de l'empreinte n'est qu'une brique, pas un système complet.

Conclusion

Le hachage SHA-256 de VeriFactu est simple à écrire et facile à rater. Fixez l'ordre des champs, normalisez chaque valeur, encodez en UTF-8, mettez le résultat en majuscules, puis protégez la chaîne contre les accès concurrents avec une transaction et une contrainte d'unicité. Testez enfin avec les exemples officiels et avec des créations parallèles. Pour approfondir, consultez l'article d'origine : Implementando la huella SHA-256 de VeriFactu: 6 detalles que rompen el hash (y uno que rompe la cadena).

Ce que ça change pour vous

Si votre entreprise facture en Espagne ou travaille avec un logiciel de facturation qui y sera utilisé, la conformité sera exigée à partir de 2027. Chaque facture devra être scellée de façon à ce que toute modification ultérieure soit détectable. Une erreur dans ce scellement peut rendre vos factures non conformes, avec un risque de sanctions administratives et fiscales. Demandez dès maintenant à votre éditeur ou à votre prestataire si son outil intègre ces exigences, et comment il les teste. Mieux vaut obtenir cette réponse aujourd'hui qu'au moment d'un contrôle.

Partager cet article

Et votre site, il vaut quoi ?

Vitesse, accessibilité, référencement technique. Le rapport est écrit pour un dirigeant, pas pour un développeur. Gratuit, sans inscription.

Tester mon site