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)