Skip to main content

Manuel administration fiscale

Téléchargement de l'export

TODO

Utilisation de l'export

Cette documentation explique comment vérifier l’intégrité et l’authenticité d’un export fiscal du logiciel WInOrtho.
L’archive contient toutes les factures et leurs lignes d'une période donnée (maximum un an), avec une signature Ed25519 assurant la non-altération.
La période concernée est précisée dans le nom de l'archive.

Contenu de l’archive

export_2024-01-01_2025-07-31.zip : archive ZIP contenant le fichier l'export.
export_2024-01-01_2025-07-31.zip.sig : signature Ed25519 de l’archive ZIP.
winortho_verify_key.hex : clé publique fournie par le Présence Informatique pour vérification des données.

Le fichier JSON (export.json) contient toutes les factures et leurs lignes enfants sous cette structure : TODO: définir un format définitif
[
  {
    "numero": "000000001",
    "date": "2025-09-23",
    "montant": "1000.00",
    "previous_signature": "",
    "signature": "abc123...",
    "lignes": [
      {
        "libelle": "Acte A",
        "quantite": 1,
        "montant": "1000.00",
        "tva": "20.00"
      `
    ]
  }
]
previous_signature : chaîne avec la signature de la facture précédente pour maintenir l’intégrité de la blockchain.
signature : signature Ed25519 de la facture.

Vérification de l'archive et de la chaîne de factures


Le script suivant permet de :

  • Vérifier puis décompresser factures_archive.zip pour obtenir factures.json.
  • Charger le JSON et vérifier chaque facture et son chainage
Prérequis :

  • Python 3.x
  • Installer la librairie PyNaCl :
pip install pynacl
Le script Python

Télécharger le script

Aperçu du script pour analyse :
import json
import zipfile
from nacl.signing import VerifyKey
import hashlib

def compute_fiscal_hash(facture):
    data = {
        "numero": facture["numero"],
        "date": facture["date"],
        "montant": facture["montant"],
        "type_client": facture["type_client"],
        "lignes": sorted([
            {"libelle": l["libelle"], "quantite": l["quantite"], "montant": l["montant"], "tva": l["tva"]}
            for l in facture["lignes"]
        ], key=lambda x: x["libelle"])
    }
    json_data = json.dumps(data, sort_keys=True)
    return hashlib.sha256(json_data.encode()).hexdigest()

def verify_archive_and_chain(zip_path, sig_path, verify_key_path):
    # Charger clé publique
    with open(verify_key_path, "r") as f:
        verify_key = VerifyKey(bytes.fromhex(f.read()))

    # Vérifier signature ZIP
    with open(zip_path, "rb") as f:
        zip_bytes = f.read()
    with open(sig_path, "r") as f:
        signature_hex = f.read()
    try:
        verify_key.verify(bytes.fromhex(signature_hex), zip_bytes)
        print("✅ Signature ZIP valide")
    except:
        print("❌ Signature ZIP invalide")
        return False

    # Décompresser JSON
    with zipfile.ZipFile(zip_path, "r") as zip_file:
        with zip_file.open("factures.json") as f:
            factures = json.load(f)

    # Vérification de la chaîne
    previous_sig = None
    all_ok = True
    for facture in factures:
        fiscal_hash = compute_fiscal_hash(facture)
        data_to_verify = fiscal_hash
        if previous_sig:
            data_to_verify += previous_sig
        try:
            verify_key.verify(bytes.fromhex(facture["signature"]), data_to_verify.encode())
            print(f"✅ Facture {facture['numero']} OK")
        except:
            print(f"❌ Facture {facture['numero']} INVALIDE")
            all_ok = False
        previous_sig = facture["signature"]

    if all_ok:
        print("✅ La chaîne de factures est intacte")
    else:
        print("❌ La chaîne de factures est compromise")

    return all_ok

# Exemple d'utilisation
if __name__ == "__main__":
    verify_archive_and_chain("factures_archive.zip", "factures_archive.zip.sig", "verify_key.hex")

Interprétation des résultats

  • ✅ Facture OK : intégrité de la facture et chainage valide.
  • ❌ Facture INVALIDE : la facture a été modifiée ou la signature ne correspond pas.
  • ✅ La chaîne de factures est intacte : toutes les factures sont conformes et la blockchain interne n’a pas été altérée.
  • ❌ La chaîne de factures est compromise : au moins une facture a été modifiée, ce qui invalide toute la suite.

Notes importantes


L’éditeur fournit une archive contenant une chaîne de factures intègre. Cette chaîne est vérifiée automatiquement lors de la génération de l’archive.
Si, lors de votre propre vérification, la chaîne apparaît comme compromise, cela signifie que le fichier factures.json a été modifié en dehors du logiciel et ne doit pas être utilisé.