PD-24 — Authentification SRP-6a (Phase 1)¶
📚 Navigation User Story
| Document | | | ---------- | -- | | 📋 **Spécification** | *(ce document)* | | 🛠️ [Plan d'implémentation](PD-24-plan.md) | | | ✅ [Critères d'acceptation](PD-24-acceptability.md) | | | 📝 [Retour d'expérience](PD-24-rex.md) | | [← Retour à crypto-proof](../PD-189-epic.md) · [↑ Index User Story](index.md)Références¶
- EPIC : PD-189 — CRYPTO
- JIRA : PD-24
- Normes : RFC 5054 (SRP-6a), SHA3-256
- Dépendances crypto : Argon2id (pré-traitement mot de passe)
Objectif¶
Implémenter la Phase 1 du protocole SRP-6a dans le cadre du socle cryptographique ProbatioVault, afin de garantir une authentification strictement zero-knowledge :
- le mot de passe utilisateur ne transite jamais vers le backend ;
- aucun secret exploitable n'est stocké côté serveur ;
- l'authentification repose exclusivement sur des preuves cryptographiques.
Cette User Story met en place l'initialisation complète du protocole SRP et prépare les éléments nécessaires à la Phase 2 (calcul du secret partagé et preuves mutuelles).
Description fonctionnelle¶
La Phase 1 du protocole SRP-6a couvre deux moments distincts :
À l'inscription¶
- Le client dérive localement un verifier cryptographique à partir du mot de passe utilisateur.
- Le serveur reçoit et stocke uniquement :
- un salt utilisateur ;
- un verifier SRP.
- Aucun élément ne permet au serveur de reconstituer le mot de passe.
À la connexion (initialisation SRP)¶
- Le client initie l'authentification sans révéler le mot de passe.
- Le serveur génère un secret éphémère et retourne un challenge public.
- Les deux parties valident cryptographiquement les paramètres échangés.
- Les éléments nécessaires à la Phase 2 sont préparés, sans encore calculer le secret partagé.
Diagrammes de flux¶
Inscription¶
┌─────────────────────────────────────────────────────────────────────────────┐
│ INSCRIPTION │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client (React Native) Serveur (NestJS) │
│ ──────────────────── ──────────────── │
│ │
│ 1. salt = random(16 bytes) │
│ 2. K_auth = Argon2id(password, salt, │
│ "ProbatioVault_SRP_Auth_v1") │
│ 3. x = SHA3-256(salt || K_auth) │
│ 4. verifier = g^x mod N │
│ │
│ ────── POST /auth/register ──────> │
│ {email, salt, verifier} │
│ 5. Valide salt (16-32 bytes) │
│ 6. Valide verifier ∈ [1, N-1] │
│ 7. Stocke {email, salt, v} │
│ <────── 201 Created ────────────── │
│ {userId} │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Authentification (Phase 1 - Challenge)¶
┌─────────────────────────────────────────────────────────────────────────────┐
│ AUTHENTIFICATION - Phase 1 Challenge │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client Serveur │
│ ────── ─────── │
│ │
│ 1. a = random(256 bits) [SECRET] │
│ 2. A = g^a mod N │
│ │
│ ────── POST /auth/login/challenge ──> │
│ {email, A} │
│ 3. Valide A mod N ≠ 0 │
│ 4. Récupère {salt, v} du user │
│ 5. b = random(256 bits) │
│ 6. B = k*v + g^b mod N │
│ 7. Stocke session {A,b,B,v} │
│ <────── {salt, B} ─────────────────── │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Diagrammes Mermaid¶
Séquence — Inscription Zero-Knowledge¶
Ce diagramme détaille l'échange client-serveur à l'inscription. Les validations serveur (salt 16-32 bytes, verifier dans [1, N-1]) garantissent qu'aucun paramètre dégénéré n'est accepté (cf. Contraintes de validation).
sequenceDiagram
participant C as Client (React Native)
participant S as Serveur (NestJS)
Note over C: salt = random(16 bytes)
Note over C: K_auth = Argon2id(password, salt,<br/>"ProbatioVault_SRP_Auth_v1")
Note over C: x = SHA3-256(salt || K_auth)
Note over C: verifier = g^x mod N
C->>S: POST /auth/register {email, salt, verifier, plan}
Note over S: Valide salt (16-32 bytes hex)
Note over S: Valide verifier ∈ [1, N-1]
Note over S: Stocke {email, salt, verifier}
S-->>C: 201 Created {userId}
Note over C,S: INV: le mot de passe ne transite jamais (Zero-Knowledge)
Note over C,S: INV: le serveur ne stocke ni password, ni x, ni K_auth Séquence — Authentification Phase 1 (Challenge SRP-6a)¶
Ce diagramme détaille l'échange challenge-response de la Phase 1. Les validations A mod N != 0 et B mod N != 0 empêchent les attaques par paramètre nul (cf. Sécurité cryptographique).
sequenceDiagram
participant C as Client
participant S as Serveur
Note over C: a = random(≥256 bits) [SECRET]
Note over C: A = g^a mod N
C->>S: POST /auth/login/challenge {email, A}
Note over S: Valide A mod N ≠ 0
Note over S: Récupère {salt, verifier} du user
Note over S: b = random(≥256 bits) [SECRET]
Note over S: B = k*v + g^b mod N
Note over S: Stocke session SRP {A, b, B, v}
S-->>C: 200 OK {salt, B}
Note over C: Valide B mod N ≠ 0
Note over C: u = SHA3-256(A || B)
Note over C: Valide u ≠ 0
Note over C,S: INV: secrets éphémères (a, b) ≥ 256 bits CSPRNG
Note over C,S: INV: rejet immédiat si A mod N = 0 ou B mod N = 0 ou u = 0
Note over C,S: INV: session SRP à usage unique, TTL 5 min État — Session SRP éphémère¶
La session SRP côté serveur traverse 4 états. Le TTL de 5 minutes et le caractère single-use protègent contre le replay (cf. Sécurité — Session hijacking).
stateDiagram-v2
[*] --> CREATED : POST /auth/login/challenge<br/>A valide (A mod N ≠ 0)
CREATED --> VERIFIED : Phase 2 — M1 valide (PD-25)
CREATED --> EXPIRED : TTL 5 min dépassé
CREATED --> REJECTED : A mod N = 0<br/>ou u = 0<br/>ou M1 invalide
VERIFIED --> CONSUMED : Session key émise (PD-25)
VERIFIED --> [*]
EXPIRED --> [*]
REJECTED --> [*]
CONSUMED --> [*]
note right of CREATED
Stocke {A, b, B, v}
Usage unique (single-use)
INV: effacement mémoire best-effort
des secrets éphémères après consommation
end note
note right of EXPIRED
Nettoyage automatique
par job de purge
end note API Endpoints¶
GET /auth/srp-params¶
Récupère les paramètres publics SRP.
Response 200:
POST /auth/register¶
Inscription Zero-Knowledge.
Request:
{
"email": "user@example.com",
"salt": "a1b2c3d4e5f6...",
"verifier": "f6e5d4c3b2a1...",
"plan": "free"
}
Response 201:
{
"message": "Utilisateur enregistré avec succès",
"userId": "123e4567-e89b-12d3-a456-426614174000"
}
POST /auth/login/challenge¶
Phase 1 : Initialise le challenge SRP.
Request:
Response 200:
Périmètre¶
Inclus¶
- Génération client-side du salt et du verifier SRP à l'inscription.
- Stockage serveur sécurisé du salt et du verifier.
- Initialisation du protocole SRP-6a à la connexion :
- génération de A côté client ;
- génération de B côté serveur ;
- calcul et validation de u.
- Validation cryptographique stricte des paramètres échangés.
- API d'initialisation SRP.
- Tests de conformité et de sécurité.
Exclu¶
- Phase 2 SRP-6a (calcul du secret partagé, preuves M1/M2, génération de session).
- Émission de JWT ou gestion de session.
- MFA, refresh tokens, rotation de clés.
- Chiffrement client-side des données.
- Gestion HSM ou audit probatoire.
Paramètres cryptographiques normatifs¶
Les paramètres suivants sont obligatoires et non négociables :
Groupe SRP¶
| Élément | Valeur |
|---|---|
| Groupe | Safe Prime 3072 bits (RFC 5054 Group 15) |
| Référence | RFC 5054 — Appendix A (group 15) |
| Générateur | g = 2 |
Fonctions de hash¶
| Usage | Algorithme |
|---|---|
| Hash SRP | SHA3-256 |
| k = H(N \ | \ |
| u = H(A \ | \ |
Secrets éphémères¶
a(client) : ≥ 256 bits aléatoiresb(serveur) : ≥ 256 bits aléatoires
Pré-traitement mot de passe¶
Avant SRP :
- Le mot de passe est dérivé via Argon2id.
- La valeur résultante est intégrée dans le calcul de
x.
Propriétés attendues¶
Zero-Knowledge¶
- Le mot de passe utilisateur ne quitte jamais le client.
- Le serveur ne stocke jamais :
- le mot de passe ;
x;A,S,M1,M2.- Les échanges réseau ne permettent aucune attaque par dictionnaire offline.
Sécurité cryptographique¶
- Validation stricte :
A mod N ≠ 0B mod N ≠ 0u ≠ 0- Rejet immédiat en cas de paramètre invalide.
- Effacement mémoire best-effort des secrets éphémères.
Interopérabilité¶
- Implémentation conforme RFC 5054.
- Résultats déterministes et reproductibles.
- Compatible avec la Phase 2 (PD-25).
Sécurité¶
Protections implémentées¶
| Attaque | Protection |
|---|---|
| Interception réseau | Le password ne transite jamais |
| Base de données compromise | Le verifier ne permet pas de retrouver le password |
| Replay attack | Éphémères uniques par session |
| Man-in-the-middle | Authentification mutuelle (M1/M2 en Phase 2) |
| A = 0 attack | Validation A mod N ≠ 0 |
| Timing attack | Délai aléatoire côté serveur |
| Session hijacking | Sessions SRP à usage unique, TTL 5 min |
| Brute force offline | Argon2id memory-hard (64 MiB) |
Contraintes de validation¶
| Paramètre | Contrainte |
|---|---|
| Salt | 16-32 bytes, hexadécimal |
| Verifier | 1 < v < N, hexadécimal |
| A | A mod N ≠ 0, hexadécimal |
| M1 | 64 caractères hex (32 bytes) |
| Password | Min 12 caractères (prod), 4 (dev) |
Contraintes¶
- Implémentation strictement conforme SRP-6a.
- Aucun fallback vers un schéma d'authentification plus faible.
- Aucun log de données sensibles.
- Limitation des tentatives et protection DoS.
- Timeout des échanges SRP incomplets.
Hypothèses¶
- Le client dispose d'un générateur CSPRNG fiable.
- Les paramètres SRP sont figés et partagés par toutes les plateformes.
- Le backend peut maintenir un état temporaire de session SRP.
- La Phase 2 est implémentée séparément.
Tests d'acceptation¶
TA-1 — Inscription SRP¶
- Le serveur stocke uniquement
saltetverifier. - Aucune donnée sensible n'est persistée.
TA-2 — Initialisation SRP¶
- Le serveur retourne
{ salt, B }. Les paramètres publicsNetgsont fournis viaGET /auth/srp-params(constants RFC 5054) et ne sont pas renvoyés dans chaque challenge. B mod N ≠ 0.
TA-3 — Génération client de A¶
A mod N ≠ 0.- Aucune fuite du secret
a.
TA-4 — Calcul de u¶
u = H(A || B)calculé correctement.- Rejet si
u = 0.
TA-5 — Zero-Knowledge¶
- Inspection réseau :
- aucun mot de passe ;
- aucun dérivé Argon2id ;
- aucun secret SRP.
TA-6 — Conformité RFC¶
- Calculs conformes aux vectors SRP officiels.
- Groupe N=3072 bits (RFC 5054 Group 15) strictement respecté.
TA-7 — Préparation Phase 2¶
- Le serveur dispose de tous les éléments nécessaires pour enchaîner immédiatement vers PD-25.
Livrables¶
- Implémentation client SRP Phase 1.
- Implémentation backend SRP Phase 1.
- Tests unitaires cryptographiques.
- Documentation
/docs/auth/srp/phase1/. - Rapport de conformité sécurité.
Liens documentaires¶
- EPIC : PD-189 — CRYPTO
- RFC 5054 — Secure Remote Password
- Architecture Zero-Knowledge ProbatioVault
- PD-25 — SRP-6a Phase 2
Definition of Done¶
- Flux SRP Phase 1 fonctionnel.
- Paramètres cryptographiques conformes.
- Zero-knowledge vérifié.
- Tests unitaires et d'intégration validés.
- Documentation publiée.
- Revue sécurité approuvée.