Aller au contenu

PD-40 — Rotation de clés HSM et re-signature probatoire (EPIC : PD-189 — CRYPTO)

1. Objectif

Définir le contrat canonique d’une procédure de rotation de clés de signature gérées par HSM, incluant : - génération d’une nouvelle clé Ed25519 dans le HSM, - re-signature d’un ensemble déterministe et borné d’événements, - modèle de multi-signature additive append-only avec atomicité, - archivage contrôlé des clés précédentes, - journalisation d’audit durable et exportable,

afin de garantir la vérifiabilité historique, la robustesse opérationnelle et la conformité sécurité.


2. Périmètre et politique de rotation

2.1 Périmètre

  • Clés asymétriques de signature hébergées dans un HSM certifié (§6).
  • Rotation déclenchée par un acteur autorisé.
  • Re-signature additive (aucune suppression/modification de signatures existantes).
  • Archivage des clés remplacées.
  • Audit/export/rétention des journaux.

2.2 Déclencheurs autorisés (normatif)

Une rotation peut être déclenchée uniquement par : - Action manuelle d’un acteur autorisé. - Incident de sécurité (compromission suspectée/avérée). - Exigence de conformité (réglementaire/contractuelle).

Tout autre déclencheur est interdit.

2.3 Fréquence de référence

  • Fréquence de référence : 12 mois.
  • Rotation anticipée : autorisée à tout moment.
  • La fréquence est documentée et auditée, sans automatisme implicite.

2.4 Politique de transition des clés (normatif)

  • Unicité stricte de la clé active : à tout instant, une et une seule clé peut produire des signatures ACTIVE.
  • Il n’existe aucune période avec deux clés actives.
  • Une clé nouvellement générée est CANDIDATE tant que la rotation n’est pas validée.

3. Définitions

  • Append-only : interdiction de supprimer/modifier des enregistrements déjà persistés.
  • Événement probatoire : enregistrement immuable décrivant une action.
  • Signature probatoire : preuve cryptographique d’intégrité/attribution associée à une clé (keyId).
  • Signature CANDIDATE : signature produite pendant une rotation non validée.
  • Signature ACTIVE : signature valide et prise en compte par la vérification fonctionnelle.
  • rotation_id : identifiant unique d’une tentative de rotation.
  • rotation_start_time : horodatage de début de rotation.

4. Modèle normatif des événements et signatures

4.1 Canonicalisation

  • La représentation à signer est le JSON canonique selon RFC 8785.
  • La canonicalisation s’applique à l’objet EventToSign (§4.2), pas au stockage global.

4.2 Schéma minimal obligatoire d’un événement

Chaque événement doit contenir au minimum :

{
  "event_id": "uuid-v4",
  "timestamp": "ISO-8601",
  "type": "EVENT_TYPE",
  "payload_hash": "SHA3-256(hex)",
  "status": "FINALIZED | PENDING | FAILED | CANCELLED",
  "signatures": [ /* SignatureEntry[] */ ]
}

Règles - event_id, timestamp, type, payload_hash, status sont immutables après FINALIZED. - payload_hash est l’empreinte du contenu métier (contenu hors périmètre).

4.3 Objet effectivement signé

L’objet signé (EventToSign) est :

{
  "event_id": "...",
  "timestamp": "...",
  "type": "...",
  "payload_hash": "..."
}

4.4 Entrée de signature (multi-signature additive avec état)

signatures[] est un tableau d’objets append-only de type :

{
  "keyId": "string",
  "algorithm": "Ed25519",
  "signature": "base64",
  "signed_at": "ISO-8601",
  "rotation_id": "uuid",
  "state": "CANDIDATE | ACTIVE"
}

Règles normatives 1. Aucune entrée signatures[] n’est jamais supprimée ni modifiée après persist (append-only). 2. Une signature n’est valide que si state = ACTIVE. 3. Les signatures CANDIDATE sont ignorées par la vérification fonctionnelle. 4. L’ordre logique de signatures[] est : (signed_at ASC, keyId ASC).


5. Définition normative de l’ensemble des événements éligibles (E)

La re-signature s’applique exclusivement à l’ensemble E défini ci-dessous.

Un événement appartient à E si et seulement si toutes les conditions suivantes sont vraies :

5.1 Fenêtre temporelle

Soit rotation_start_time l’instant de début de rotation.

  • ΔT = 24 heures (valeur normative).
  • Condition :
event.timestamp ∈ ]rotation_start_time − ΔT ; rotation_start_time[

5.2 Types éligibles (liste fermée)

CREATE
UPDATE_METADATA
ACCESS_LOG
PRE_DELEGATION
REKEY
Tout autre type est exclu.

5.3 Statut

  • status = FINALIZED uniquement.

5.4 Bornage volumétrique

  • N_max = 100 000 événements par rotation.
  • Si |E| > N_max ⇒ la rotation échoue explicitement (aucune promotion).

5.5 Ordre déterministe

L’ensemble E est traité dans l’ordre strict :

(timestamp ASC, event_id ASC)

6. Paramètres cryptographiques et exigences HSM (normatif)

6.1 Algorithme unique autorisé

L’algorithme de signature autorisé est uniquement : - EdDSA / Ed25519 - taille : 256 bits (intrinsèque) - hash : SHA-512 (Ed25519)

Tout autre algorithme est interdit dans cette version de PD-40.

6.2 Génération et usage des clés

  • Génération exclusivement dans le HSM.
  • Clés privées non exportables.
  • Signature uniquement dans le HSM.

6.3 Certification minimale du HSM

Le HSM doit satisfaire au minimum : - FIPS 140-2 niveau 3 ou supérieur, ou - FIPS 140-3 niveau 3 ou supérieur, ou - RGS v2 niveau 2+ (France / ANSSI).

6.4 Métadonnées de clés exportables

Le système doit pouvoir exporter (hors secret) : - keyId immuable - algorithm - date de génération - statut (CANDIDATE, ACTIVE, ARCHIVED)


7. Invariants (non négociables)

  1. Les clés privées ne sortent jamais du HSM.
  2. Les signatures sont produites exclusivement par le HSM.
  3. Unicité stricte de la clé active (une seule clé peut produire des signatures ACTIVE).
  4. Une clé archivée ne peut jamais produire de signatures ACTIVE.
  5. Le modèle est append-only (événements et signatures).
  6. Une signature n’est valide que si state = ACTIVE.
  7. Toute signature ACTIVE reste vérifiable.
  8. Atomicité par promotion d’état : soit toutes les signatures CANDIDATE d’une rotation sont promues, soit aucune.
  9. La sélection E est déterministe, bornée et testable.
  10. Toute rotation est authentifiée, autorisée, journalisée et exportable.

8. Flux nominaux (normatif)

N1 — Déclenchement

  1. Un acteur autorisé déclenche la rotation.
  2. Le système crée : rotation_id et rotation_start_time.

N2 — Génération de clé

  1. Le HSM génère une nouvelle clé Ed25519.
  2. Attribution d’un keyId.
  3. Statut clé : CANDIDATE.

N3 — Construction de l’ensemble E

  1. Sélection déterministe des événements selon §5.
  2. Vérification |E| ≤ N_max.

N4 — Re-signature (phase CANDIDATE)

Pour chaque événement de E : 1. Construire EventToSign (§4.3) en JSON canonique RFC 8785. 2. Signer via HSM (Ed25519). 3. Ajouter une SignatureEntry avec state=CANDIDATE et rotation_id.

N5 — Promotion atomique

Si et seulement si toutes les signatures CANDIDATE ont été produites avec succès : - Promouvoir atomiquement toutes les signatures CANDIDATE de ce rotation_id en ACTIVE. - Marquer la clé candidate ACTIVE. - Marquer l’ancienne clé ARCHIVED.

N6 — Échec

Si une seule re-signature échoue : - Aucune promotion n’a lieu. - La clé candidate est abandonnée (reste CANDIDATE puis DISCARDED ou supprimée côté HSM si possible, hors secret). - Les signatures CANDIDATE éventuellement écrites restent inactives et ignorées.


8bis. Diagrammes

Diagramme d’états — Cycle de vie d’une clé HSM

stateDiagram-v2
    [*] --> CANDIDATE : N2 — HSM génère Ed25519\n(attribution keyId)

    CANDIDATE --> ACTIVE : N5 — Promotion atomique\n(toutes signatures OK)
    CANDIDATE --> DISCARDED : N6 — Échec re-signature\n(abandon clé)

    ACTIVE --> ARCHIVED : N5 — Nouvelle clé promue\n(remplacement)

    ARCHIVED --> [*]
    DISCARDED --> [*]

    note right of CANDIDATE
        Clé générée dans le HSM.
        Signatures produites = state CANDIDATE.
        Ignorées par la vérification fonctionnelle.
    end note

    note right of ACTIVE
        Unicité stricte (INV-3) :
        une et une seule clé ACTIVE
        à tout instant.
    end note

    note right of ARCHIVED
        Clé archivée (INV-4) :
        ne peut jamais produire
        de signatures ACTIVE.
        Signatures historiques
        restent vérifiables (INV-7).
    end note

    note right of DISCARDED
        Clé abandonnée après échec.
        Aucune signature promue.
        Supprimée côté HSM si possible.
    end note

Diagramme d’états — Cycle de vie d’une signature

stateDiagram-v2
    [*] --> CANDIDATE : N4 — Re-signature via HSM\n(rotation_id, keyId)

    CANDIDATE --> ACTIVE : N5 — Promotion atomique\n(rotation réussie)
    CANDIDATE --> CANDIDATE : N6 — Échec rotation\n(reste inactive, ignorée)

    ACTIVE --> [*]

    note right of CANDIDATE
        Ignorée par la vérification
        fonctionnelle (INV-6).
        Jamais supprimée (INV-5, append-only).
    end note

    note right of ACTIVE
        Signature valide et vérifiable (INV-6, INV-7).
        Jamais modifiée ni supprimée (INV-5).
    end note

Diagramme de séquence — Flux de rotation nominal (N1→N5)

sequenceDiagram
    actor Acteur as Acteur autorisé
    participant Sys as Système de rotation
    participant HSM as HSM (FIPS 140-2 L3+)
    participant DB as Base de données<br/>(append-only)
    participant Audit as Journal d’audit<br/>(WORM)

    Note over Acteur,Audit: N1 — Déclenchement

    Acteur->>Sys: Déclencher rotation<br/>(manuel / sécurité / conformité)
    Sys->>Sys: Créer rotation_id + rotation_start_time
    Sys->>Audit: Log ROTATION_STARTED<br/>(rotation_id, initiateur, déclencheur)

    Note over Acteur,Audit: N2 — Génération de clé

    Sys->>HSM: Générer clé Ed25519
    HSM-->>Sys: keyId (new_keyId), clé publique
    Sys->>DB: Persister clé {new_keyId, CANDIDATE, Ed25519}
    Sys->>Audit: Log KEY_GENERATED<br/>(new_keyId, algorithm=Ed25519)

    Note over Acteur,Audit: N3 — Construction de E

    Sys->>DB: SELECT événements WHERE<br/>timestamp ∈ ]t−24h ; t[<br/>AND type ∈ {CREATE, UPDATE_METADATA, ...}<br/>AND status = FINALIZED<br/>ORDER BY (timestamp ASC, event_id ASC)
    DB-->>Sys: Ensemble E (|E| événements)

    alt |E| > N_max (100 000)
        Sys->>Audit: Log ROTATION_FAILED<br/>(cause: |E| > N_max)
        Sys->>DB: Clé new_keyId → DISCARDED
        Note over Sys: STOP — Aucune promotion
    end

    Note over Acteur,Audit: N4 — Re-signature (phase CANDIDATE)

    loop Pour chaque événement e ∈ E (ordre déterministe)
        Sys->>Sys: Construire EventToSign(e)<br/>(JSON canonique RFC 8785)
        Sys->>HSM: Signer(EventToSign, new_keyId)
        HSM-->>Sys: signature (Ed25519, base64)
        Sys->>DB: APPEND SignatureEntry<br/>{new_keyId, Ed25519, signature,<br/>signed_at, rotation_id, state=CANDIDATE}
    end

    Note over Acteur,Audit: N5 — Promotion atomique

    alt Toutes signatures CANDIDATE produites OK
        Sys->>DB: BEGIN TRANSACTION
        Sys->>DB: UPDATE signatures SET state=ACTIVE<br/>WHERE rotation_id AND state=CANDIDATE
        Sys->>DB: UPDATE clé new_keyId → ACTIVE
        Sys->>DB: UPDATE clé old_keyId → ARCHIVED
        Sys->>DB: COMMIT (atomique — INV-8)
        Sys->>Audit: Log ROTATION_SUCCESS<br/>(old_keyId→ARCHIVED, new_keyId→ACTIVE,<br/>eligible_count=|E|)
    else Échec d’au moins une re-signature (N6)
        Sys->>DB: Clé new_keyId → DISCARDED
        Note over DB: Signatures CANDIDATE restent<br/>inactives et ignorées (INV-5, INV-6)
        Sys->>Audit: Log ROTATION_FAILED<br/>(cause, event_id en échec)
    end

9. Cas d’erreur (extraits)

  • E4 — Échec partiel de re-signature :
  • aucune promotion d’état,
  • aucune nouvelle signature ACTIVE n’apparaît,
  • aucune clé n’est activée,
  • état cohérent append-only.

Clarification : le terme « rollback » signifie absence de promotion (pas de suppression).


10. Journalisation, audit et conformité (normatif)

10.1 Contenu du journal de rotation

Chaque rotation (succès ou échec) produit un enregistrement immuable contenant a minima : - rotation_id - rotation_start_time, rotation_end_time - déclencheur (manuel/sécurité/conformité) - initiateur (identité) - old_keyId, new_keyId - algorithm=Ed25519 - eligible_count=|E| - liste des event_id re-signés (ou un hash de liste + pagination si volumineux) - statut final (SUCCESS / ROTATION_FAILED) - cause détaillée en cas d’échec

10.2 Format

  • NDJSON ou JSON canonique (RFC 8785).

10.3 Immutabilité

  • Stockage append-only (WORM ou équivalent).

10.4 Rétention

  • Durée minimale : 10 ans.

10.5 Export

  • Export à tout moment en NDJSON/JSON canonique.
  • Export ne requiert aucun accès aux clés privées.

11. Critères d’acceptation (testables)

  • CA1 : À tout instant, il existe exactement une clé pouvant produire des signatures ACTIVE.
  • CA2 : Un événement signé avant rotation reste vérifiable via une signature ACTIVE existante.
  • CA3 : Une clé archivée ne peut jamais produire de signatures ACTIVE.
  • CA4 : Chaque signature expose keyId et algorithm = Ed25519.
  • CA5 : Après succès, tous et uniquement les événements de l’ensemble E possèdent une signature ACTIVE supplémentaire associée au new_keyId.
  • CA6 : En cas d’échec, aucune signature ACTIVE supplémentaire n’est observable (uniquement des CANDIDATE éventuelles, ignorées).
  • CA7 : Un journal d’audit complet, durable, exportable est produit pour chaque rotation.

12. Points désormais clos

  • Périmètre E (fenêtre / types / statut / N_max) déterministe et testable
  • Modèle rollback cohérent avec append-only (promotion d’état)
  • Paramètres cryptographiques et exigences HSM normés (Ed25519 + certifications)
  • Format d’événement et encodage multi-signature explicités