Aller au contenu

📝 RETOUR D'EXPÉRIENCE (REX)


📚 Navigation User Story | Document | | | ---------- | -- | | 📋 SpĂ©cification | [PD-25-specification.md](PD-25-specification.md) | | đŸ› ïž Plan d'implĂ©mentation | [PD-25-plan.md](PD-25-plan.md) | | ✅ CritĂšres d'acceptation | [PD-25-acceptability.md](PD-25-acceptability.md) | | 📝 **Retour d'expĂ©rience** | *(ce document)* | [← Retour Ă  crypto-proof](../PD-189-epic.md) · [↑ Index User Story](index.md)

PD-25 — Authentification SRP-6a (Phase 2 : preuve, clĂ© de session, token)

📌 EPIC âžĄïž PD-189 — CRYPTO

📌 Artefact produit âžĄïž PD-25-rex.md


1. Résumé exécutif

Dimension Évaluation
ConformitĂ© spec 🟡 Partielle — 1 Ă©cart majeur (E-01)
Couverture invariants 6/7 validĂ©s — INV-3 nĂ©cessite correction
Dette technique ModĂ©rĂ©e — Correction K timing requise
Risques résiduels Faibles aprÚs correction E-01

SynthĂšse : L'implĂ©mentation PD-25 respecte l'architecture Zero-Knowledge SRP-6a et couvre la majoritĂ© des invariants de sĂ©curitĂ©. Un Ă©cart majeur a Ă©tĂ© identifiĂ© concernant le timing de dĂ©rivation de la clĂ© de session (INV-3). La traçabilitĂ© audit (INV-7) a Ă©tĂ© correctement implĂ©mentĂ©e. Statut : ACCEPTÉ AVEC RÉSERVES.


2. Points fluides

2.1 Intégration AuditService (INV-7)

L'intégration de l'AuditService dans AuthService s'est déroulée sans friction :

  • Import AuditModule dans auth.module.ts : trivial
  • Injection AuditService dans le constructeur : pattern NestJS standard
  • Appels auditService.log() aux points clĂ©s : code fourni dans le plan

Temps réel : ~30 minutes (vs 2h estimées)

2.2 Gestion des erreurs déterministe

La matrice d'erreurs définie en spec §6 était directement transposable en code :

// Pattern clair et répétable
if (!session) throw new UnauthorizedException('Session SRP expirée ou invalide');
if (expired) throw new UnauthorizedException('Session SRP expirée');
if (m1Invalid) throw new UnauthorizedException('Identifiants invalides');

2.3 Suppression session Redis

Le mécanisme de nettoyage session aprÚs usage (succÚs ou échec) était déjà implémenté dans PD-24, facilitant la garantie d'usage unique.


3. Points difficiles

3.1 Séquencement calcul K vs validation M1 (E-01)

ProblÚme : Le protocole SRP-6a nécessite de calculer K' (candidat) pour vérifier M1 (car M1 = SHA3-256(A||B||K)). La distinction entre "K' candidat" et "K établie" n'était pas explicite dans l'implémentation initiale.

Impact : Le code retourne sessionKey dans l'objet rĂ©sultat mĂȘme si M1 est invalide, violant INV-3 ("clĂ© de session dĂ©rivĂ©e qu'aprĂšs vĂ©rification rĂ©ussie").

Difficulté : Tension entre l'algorithme SRP qui impose de calculer K' avant de pouvoir vérifier M1, et l'invariant qui interdit "d'établir" K avant validation.

Solution recommandée : Refactorer verifyClientProof() pour : 1. Calculer K' comme variable locale 2. Vérifier M1 avec K' 3. Ne retourner K que si M1 valide (actuellement, K est toujours calculée et retournée)

3.2 Distinction sémantique "candidat" vs "établie"

Le plan d'implémentation §2.1 documente bien cette distinction :

"K' est une valeur candidate [...] La clé de session K n'est établie qu'aprÚs vérification réussie de M1"

Cette subtilité protocolaire n'était pas immédiatement évidente et a nécessité une relecture approfondie de RFC 5054.


4. HypothÚses révélées tardivement

4.1 Disponibilité Redis (H-1)

L'hypothÚse "Redis disponible et opérationnel" n'a pas de fallback défini. En cas d'indisponibilité Redis, toute authentification SRP échoue silencieusement.

Recommandation : Ajouter health check Redis dans le endpoint /health et circuit breaker.

4.2 Vérification M2 cÎté client (H-6)

L'hypothÚse "Client implémente vérification M2" n'est pas vérifiable cÎté serveur. Si le client ignore M2, l'authentification mutuelle n'est pas garantie.

Impact : Réduit le niveau de sécurité de "authentification mutuelle" à "authentification client uniquement".

4.3 Synchronisation horloges (H-3)

Le TTL session Redis (5 min) suppose des horloges synchronisées. Un décalage serveur > 5 min invaliderait toutes les sessions.


5. Invariants complexes

5.1 INV-3 : Clé de session aprÚs vérification

ComplexitĂ© : ⭐⭐⭐ (⅗)

Cet invariant entre en tension avec l'algorithme SRP-6a lui-mĂȘme. La solution requiert de distinguer clairement : - Calcul de K' (nĂ©cessaire pour vĂ©rifier M1) - Établissement de K (aprĂšs M1 validĂ©)

Le code actuel ne fait pas cette distinction explicitement.

5.2 INV-4 : Clé de session jamais persistée

ComplexitĂ© : ⭐ (⅕)

Facile Ă  garantir : variable locale dans scope fonction, pas d'appel Ă  Redis/DB avec K.

5.3 INV-7 : Traçabilité

ComplexitĂ© : ⭐⭐ (⅖)

L'infrastructure AuditService existante rendait l'implémentation straightforward. Seul point d'attention : ne pas logger d'éléments sensibles (M1, K).


6. Dette technique

ID Description Priorité Effort
DETTE-01 Refactorer verifyClientProof() pour ne retourner K qu'aprĂšs M1 valide Haute 2h
DETTE-02 Ajouter tests unitaires explicites pour timing K Moyenne 1h
DETTE-03 Rate limiting /auth/login/* (recommandation §5.3) Moyenne 2h
DETTE-04 Health check Redis dans AuthModule Basse 1h

Total dette : ~6h de travail


7. Risques résiduels

Risque Probabilité Impact Mitigation
K exposée sur échec M1 (E-01) Moyenne Moyen Correction DETTE-01 obligatoire
Replay attack si TTL trop long Faible ÉlevĂ© TTL 5 min validĂ©
ÉnumĂ©ration utilisateurs Faible Faible RĂ©ponses 401 uniformes
DoS sur sessions Redis Moyenne Moyen Rate limiting recommandé

Risque rĂ©siduel global : ModĂ©rĂ© — Acceptable aprĂšs correction E-01.


8. Améliorations processus

8.1 Spécification

  • AmĂ©lioration : PrĂ©ciser dans la spec la distinction "calcul K'" vs "Ă©tablissement K" pour lever l'ambiguĂŻtĂ© INV-3.
  • Template : Ajouter une section "Contraintes protocolaires" pour les protocoles crypto avec sĂ©quencement complexe.

8.2 Revue de code

  • AmĂ©lioration : Checklist spĂ©cifique "timing secrets cryptographiques" pour les revues de code crypto.
  • Outil : Ajouter rĂšgle SonarQube custom pour dĂ©tecter les retours de clĂ©s avant validation.

8.3 Tests

  • AmĂ©lioration : Ajouter tests nĂ©gatifs explicites : "K ne doit PAS ĂȘtre dans le rĂ©sultat si M1 invalide".

9. Enseignements clés

9.1 Pour ce projet

  1. SRP-6a impose un sĂ©quencement contraint : K' doit ĂȘtre calculĂ©e pour vĂ©rifier M1, mais ne doit ĂȘtre "Ă©tablie" (retournĂ©e/utilisĂ©e) qu'aprĂšs. Cette subtilitĂ© doit ĂȘtre documentĂ©e et testĂ©e explicitement.

  2. Les invariants "négatifs" sont plus subtils : "Ne PAS dériver K avant validation" est plus difficile à garantir que "tracer toutes les tentatives".

  3. L'intégration audit NestJS est triviale : Le pattern Module/Service/Inject rend l'ajout de traçabilité quasi-automatique.

9.2 Pour les futurs développements

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

  2. Tester les non-comportements : Ajouter des tests qui vérifient ce qui NE doit PAS se produire (ex: K non retournée si échec).

  3. Distinguer calcul/établissement : Pour tout secret cryptographique, distinguer "valeur candidate calculée" de "valeur établie/utilisable".


10. Métriques

Métrique Valeur
Temps estimé 9h
Temps réel ~4h (hors correction E-01)
Écarts bloquants 0
Écarts majeurs 1 (E-01)
Écarts mineurs 0
Tests ajoutés 3 scénarios Gherkin
Lignes de code modifiées ~80

Fin du retour d'expérience PD-25.