Aller au contenu

PD-25 — Rétrospective

1. Contexte

Champ Valeur
Story ID PD-25
Titre Authentification SRP-6a Phase 2
Domaine crypto-proof
Projet backend
Date complétion 2026-01-XX
Verdict ACCEPTÉ AVEC RÉSERVES

2. Métriques

Métrique Valeur
Temps estimé 9h
Temps réel ~4h (hors correction E-01)
Écarts majeurs 1 (timing K)
Tests ajoutés 3 scénarios Gherkin
Lignes modifiées ~80
Invariants couverts 6/7

3. Learnings clés

  • Séquencement calcul K' vs établissement K : SRP-6a impose de calculer K' avant de pouvoir vérifier M1, mais K ne doit être "établie" qu'après validation. Cette distinction "candidat vs établie" est critique pour la sécurité.

  • Les invariants négatifs sont plus subtils : "Ne PAS dériver K avant validation" est plus difficile à garantir que "tracer toutes les tentatives". Tester les non-comportements est essentiel.

  • Intégration AuditService triviale : Le pattern NestJS Module/Service/Inject rend l'ajout de traçabilité quasi-automatique (~30 min vs 2h estimées).

  • Documenter les tensions protocole/invariants : Quand un protocole impose un séquencement contraint, le documenter explicitement dans le plan d'implémentation.

4. Patterns applicables

Pattern existant : Audit intégré NestJS

constructor(
  private readonly auditService: AuditService,
) {}

async verifyClientProof(): Promise<VerifyResult> {
  try {
    const result = await this.doVerify();
    this.auditService.log('SRP_VERIFY_SUCCESS', { userId });
    return result;
  } catch (error) {
    this.auditService.log('SRP_VERIFY_FAILURE', { userId });
    throw error;
  }
}

Nouveau pattern : Calcul candidat vs valeur établie

Pour tout secret cryptographique, distinguer explicitement : 1. Calcul de la valeur candidate (nécessaire pour validation) 2. Établissement de la valeur (après validation réussie)

// CORRECT : K' est locale, K retournée seulement si M1 valide
const kCandidate = this.computeK(S);
if (!this.verifyM1(A, B, kCandidate, m1)) {
  throw new UnauthorizedException('Identifiants invalides');
  // kCandidate sort du scope, jamais exposée
}
return { sessionKey: kCandidate, m2: this.computeM2(A, kCandidate, m1) };

5. Signal CLAUDE.md

Priorité haute : Tests de non-comportement obligatoires.

### Tests Négatifs — Secrets cryptographiques (2026-02-XX)

Pour tout secret cryptographique (clé, token, hash), ajouter des tests vérifiant :
1. Le secret N'EST PAS retourné en cas d'échec
2. Le secret N'EST PAS logué (même en debug)
3. Le secret N'EST PAS persisté avant validation

**Template** : `expect(errorResponse.body).not.toHaveProperty('sessionKey')`

6. Conclusion

PD-25 a complété l'authentification SRP-6a Zero-Knowledge avec vérification M1/M2, dérivation de clé de session et traçabilité. L'écart E-01 (timing K) illustre la subtilité des invariants cryptographiques négatifs. Le pattern "candidat vs établie" est désormais documenté pour les futures US crypto.


Rétrospective générée 2026-02-19 (Étape 10 batch crypto-proof)