# Horodater une réponse d'IA : RFC 3161 et preuve longue durée

> Un certificat de réponse IA porte une date déclarée par son émetteur ; pour qu'elle soit opposable, Subsidia regroupe les certificats par lots dans un arbre de Merkle et fait horodater la racine (32 octets) par une autorité d'horodatage RFC 3161. Un chemin d'audit prouve ensuite qu'un certificat appartient au lot daté. Ce n'est pas une garantie illimitée : les jetons d'horodatage utilisent RSA ou ECDSA, et leur renouvellement n'est pas prévu pour l'instant.

Source : https://subsidia.protypa.fr/guides/horodatage-rfc-3161-reponses-ia · mis à jour le 2026-10-25 · Protypa

## La réponse courte

Un certificat Subsidia est une signature sur une empreinte. Deux choses peuvent le rendre contestable avec le temps : la **signature** (un algorithme peut être cassé un jour) et la **date** (elle est écrite par l'émetteur lui-même). Subsidia répond à la seconde par un horodatage RFC 3161 de lots de certificats, et à la première par une signature hybride, une identité de clé et une rotation. Aucune de ces couches ne rend le système « résistant au quantique » en soi : la dernière section dit ce qui tient et ce qui ne tient pas.

## Pourquoi la date pose problème

Dans un certificat, `issuedAt` est déclaré par l'émetteur. Sans témoin extérieur, « ce certificat existait en 2026 » n'est que notre parole. Et si l'algorithme de signature venait à être cassé, celui qui le casse pourrait fabriquer une signature valide sur n'importe quel document, y compris antidaté.

Ce qui n'est **pas** menacé de la même façon : SHA-256 (un ordinateur quantique réduit sa sécurité sans l'anéantir) et le contenu, puisque le certificat n'en contient aucun. La menace porte sur les signatures, pas sur les empreintes.

## L'horodatage RFC 3161, en clair

La [RFC 3161](https://www.rfc-editor.org/rfc/rfc3161) décrit un service de tiers de confiance, l'autorité d'horodatage (TSA). Le client lui envoie l'**empreinte** d'une donnée (jamais la donnée) avec l'identifiant de l'algorithme de hachage, et éventuellement un nonce. La TSA répond par un jeton signé qui contient l'empreinte, l'heure de génération (UTC), un numéro de série et le nonce renvoyé. Quiconque fait confiance à la TSA sait alors que cette empreinte existait à cet instant.

## Comment Subsidia l'applique : les lots de Merkle

Faire horodater chaque certificat un par un serait coûteux et bavard. Subsidia procède par lots :

1. **Toutes les heures**, s'il y a de nouveaux certificats depuis la dernière ancre, un travail prend le lot contigu de la chaîne.
2. Il construit un **arbre de Merkle** selon la [RFC 9162](https://www.rfc-editor.org/rfc/rfc9162) : une feuille vaut `sha256(0x00 ‖ empreinte)`, un nœud `sha256(0x01 ‖ gauche ‖ droite)`. À partir du deuxième lot, la racine de l'ancre précédente est la première feuille : les lots sont chaînés.
3. Il envoie à la TSA une requête dont l'empreinte est la **racine** (SHA-256, 32 octets), avec un nonce.
4. Il **vérifie le jeton avant de le stocker** : bonne empreinte, bon nonce, statut accordé, signature valide d'un certificat portant l'usage étendu d'horodatage, racine de confiance imposée si elle est configurée, et heure de génération à moins de dix minutes de l'horloge locale.
5. Il range le jeton et la racine ; les feuilles se recalculent à la demande.

Trois propriétés en découlent :

- **Seuls 32 octets quittent la machine** : la racine.
- **Un chemin d'audit** de taille logarithmique prouve qu'un certificat est une feuille de la racine datée : seuls des hash frères sont fournis, aucun autre certificat n'est révélé.
- **Horodater la racine date, par la chaîne, tous les certificats antérieurs du lot.**

En cas d'échec de la TSA, l'incident est journalisé et retenté cinq minutes plus tard ; l'ancrage ne bloque jamais une réponse.

## Vérifier une ancre vous-même

Avec le paquet `@protypa/subsidia-verify` :

```ts
const a = await (await fetch(`https://<gateway>/v1/proofs/${cert.id}/anchor`, { headers })).json()
await verifyAnchor({
  token: a.token, root: a.root, payloadHash: cert.payload_hash,
  leafIndex: a.leafIndex, leafCount: a.leafCount, auditPath: a.auditPath,
  trustedTsaCerts: [racinePem],
})
```

Le résultat indique la date de génération, l'identité de l'autorité et un détail par contrôle (structure, empreinte, nonce, signature, certificat du signataire, usage d'horodatage, validité, confiance, inclusion). **Donnez vous-même les racines de confiance** : sans elles, le contrôle de confiance vaut « non évalué » et l'identité de la TSA reste votre appréciation. La route d'ancre (`GET /v1/proofs/:id/anchor`) demande une clé d'API de l'espace de travail ; la liste des dernières ancres est publique.

## Signature hybride, clés, rotation, révocation

| Couche | Défaillance couverte |
|---|---|
| Signature hybride Ed25519 + ML-DSA-65 | Ed25519 cassé un jour |
| Identité de clé (`kid`) et rotation | Une clé vieillie ou compromise doit pouvoir être remplacée sans invalider le passé |
| Ancres RFC 3161 par lots | Date déclarée par nous seuls ; signature rejouable après une rupture |
| Engagements à clé par espace de travail | Un prompt court confirmé par dictionnaire depuis son empreinte |
| Clés scellées au repos | Une copie de la base de données ne suffit pas à forger |

**Double signature.** Un certificat v2 porte deux signatures sur les mêmes octets : Ed25519 et ML-DSA-65 (norme [FIPS 204](https://csrc.nist.gov/pubs/fips/204/final) du NIST). La liste des algorithmes exigés et les identifiants de clés sont dans les octets signés : retirer la signature ML-DSA-65 est un abaissement détectable. Les certificats v1 se vérifient comme avant.

**Rotation.** Chaque génération de clés (une Ed25519, une ML-DSA-65) a un identifiant, le `kid`, empreinte SHA-256 de la clé publique. Une seule génération est active. À la rotation, l'ancienne passe en « retirée » et **ses clés privées sont détruites** ; ses clés publiques restent publiées pour toujours, de sorte que le passé continue de se vérifier. Un certificat dont la date d'émission est postérieure à la retraite de sa clé est refusé.

**Révocation.** Une clé déclarée compromise est publiée comme révoquée. Une date déclarée par l'émetteur ne suffit plus à faire confiance à ce qu'elle a signé : le certificat n'est valide que si une ancre horodatée que vous avez vérifiée est strictement antérieure à la date de compromission. Une ancre d'une autorité inconnue pourrait être forgée par le détenteur de la clé compromise : c'est pourquoi les racines de confiance se fournissent.

## Ce que cela ne fait pas

C'est la partie qui compte le plus, et nous l'écrivons sans l'enjoliver.

- **L'hybride ne protège pas, à lui seul, un vérificateur hors ligne contre une rupture d'Ed25519.** Celui qui casse Ed25519 peut réécrire un contenu, donc la liste d'algorithmes, et le resigner en Ed25519 seul. Deux choses l'en empêchent : un vérificateur qui **exige** ML-DSA-65 (`requirePostQuantum`), ou un certificat couvert par une ancre antérieure à la rupture. Une politique datée (après une date D, un certificat non ancré et sans ML-DSA-65 n'est plus opposable) reste une décision à prendre ; tant qu'elle n'est pas publiée, la protection est à la discrétion de chaque vérificateur.
- **La confiance dans l'autorité d'horodatage est ouverte par défaut.** Sans racine imposée, le jeton est vérifié pour sa cohérence interne, mais n'importe qui peut tenir une TSA. Fournissez les racines. L'autorité configurée par défaut est jointe en `http://` : le jeton est signé, donc ce n'est pas le transport qui l'authentifie, mais un adversaire réseau peut faire échouer l'ancrage.
- **Les jetons d'horodatage utilisent eux-mêmes RSA ou ECDSA.** Un jeton de 2026 ne survit pas à un attaquant quantique mieux qu'Ed25519. Le renouvellement des horodatages (preuves d'archivage, [RFC 4998](https://www.rfc-editor.org/rfc/rfc4998)) **n'est pas prévu pour l'instant**. L'ancre donne une date opposable tant que l'algorithme de l'autorité tient, pas indéfiniment.
- **Sans ancre, la date est déclarée.** L'ancrage est actif par défaut sur le cloud, désactivé par défaut en installation locale ou sur site. Un client qui ne l'active pas n'a aucune ancre, et ne dispose alors que de l'option d'exiger ML-DSA-65.
- **Une ancre dit « cette empreinte existait avant cette date », rien de plus.** Elle n'atteste pas que la réponse est vraie, ni que l'émetteur a consigné la vérité.
- **Le délai est d'une heure au plus.** Entre l'émission et l'ancrage, le certificat est valide mais pas encore daté par un tiers.
- **Certaines empreintes ne sont pas protégées par clé.** Les étapes d'une trace d'agent, les passages cités, le texte contrôlé par le Vérificateur et les exports du registre portent des SHA-256 simples, confirmables par dictionnaire si l'on devine le contenu.
- **Stockage des clés.** Un processus sans environnement durable et sans secret maître stocke ses clés en clair ; sous Windows, les droits du fichier de clé maître reposent sur les droits du dossier. Ces faiblesses sont documentées dans nos notes techniques.
- **Le SDK n'expose pas encore `requirePostQuantum`** : il est dans `@protypa/subsidia-verify`, pas dans `@protypa/subsidia`.

## En pratique

1. **Cloud** : l'ancrage est actif. Récupérez l'ancre d'un certificat une heure après son émission.
2. **Sur site** : activez l'ancrage (variable `SUBSIDIA_ANCHOR=on`) si vous voulez une date opposable ; vous pouvez imposer vos racines de confiance (`SUBSIDIA_TSA_TRUST`).
3. **Côté vérificateur** : épinglez les identifiants de clés, fournissez les racines de confiance de la TSA, et exigez ML-DSA-65 si votre politique le demande.
4. **Conservez** le certificat et son ancre ensemble.

Pour la vérification de base, voir [Vérifier un certificat de réponse IA](/guides/verifier-un-certificat-de-reponse-ia).

## Questions fréquentes

### Qu'est-ce qu'un horodatage RFC 3161 ?

C'est un protocole standardisé par lequel on envoie à une autorité d'horodatage (TSA) l'empreinte d'une donnée, et non la donnée. L'autorité renvoie un jeton signé qui atteste que cette empreinte existait à l'instant indiqué. Le client peut joindre un nonce, que l'autorité doit renvoyer, pour écarter les réponses rejouées.

### Que quitte réellement ma machine lors de l'ancrage ?

32 octets : la racine de l'arbre de Merkle du lot. Aucun certificat, aucun contenu, aucune question ni réponse n'est transmis à l'autorité d'horodatage.

### Les certificats Subsidia sont-ils résistants à l'ordinateur quantique ?

Nous ne le prétendons pas. Chaque certificat v2 porte deux signatures (Ed25519 et ML-DSA-65), mais un vérificateur n'est protégé contre une rupture d'Ed25519 que s'il exige la signature ML-DSA-65 ou si le certificat est couvert par une ancre antérieure à la rupture. Les jetons d'horodatage utilisent eux-mêmes RSA ou ECDSA.

### L'horodatage est-il activé par défaut ?

En mode cloud, oui. En installation locale ou sur site, il est désactivé par défaut : c'est le client qui décide de l'activer. Sans ancre, la date du certificat est celle que l'émetteur déclare.

### Combien de temps faut-il pour qu'un certificat soit ancré ?

L'ancrage est horaire et ne se fait que s'il y a de nouveaux certificats depuis la dernière ancre. Tant que le certificat n'est pas horodaté, la route d'ancre répond « anchor_pending », pour une heure au plus en fonctionnement normal.

### Que se passe-t-il si une clé de signature est compromise ?

Une clé compromise peut être déclarée révoquée. Ce qu'elle a signé n'est alors valide que si une ancre horodatée antérieure à la date de compromission le prouve ; sinon le certificat est invalide. La clé privée d'une génération retirée est détruite, et ses clés publiques restent publiées.
