Aller au contenu

PD-243 — Expression de besoin

Titre

Implémenter dérivation K_auth avec HKDF (label ProbatioVault::K_auth::v1) et corriger l'anomalie PD-34


Contexte

L'architecture cryptographique ProbatioVault repose sur une hiérarchie de clés dérivées depuis K_master :

K_master (256 bits, généré aléatoirement)
    ├── HKDF → K_encryption (chiffrement fichiers)
    ├── HKDF → K_share → K_doc (isolation par document)
    └── HKDF → K_auth (authentification SRP) ← PD-243

État actuel : - K_encryption (HKDF) et K_doc (HKDF) sont implémentés dans src/services/hkdf.ts - K_auth est actuellement dérivé via Argon2id depuis le password (dans keyDerivation.ts), ce qui l'isole de la hiérarchie K_master

Problème : 1. K_auth n'est pas dérivé de K_master, ce qui brise la cohérence de la hiérarchie 2. L'architecture technique v4.1 (doc 42) spécifie que K_auth doit utiliser HKDF avec le label ProbatioVaultAuthv1 3. Anomalie PD-34 : Le label Kdoc diverge de la spécification (K_doc avec underscore)


Besoin fonctionnel

1. Implémenter dérivation K_auth via HKDF

Ajouter une fonction deriveAuthKey() dans src/services/hkdf.ts qui : - Prend K_master comme Input Key Material (IKM) - Utilise HKDF-SHA3-256 (comme K_encryption et K_doc) - Applique le label ProbatioVault::K_auth::v1 pour domain separation - Produit une clé de 32 bytes (256 bits)

2. Corriger l'anomalie PD-34 (labels HKDF)

Aligner tous les labels HKDF sur constants.ts :

Label actuel (hkdf.ts) Label corrigé (constants.ts)
ProbatioVault::Kdoc::v1 ProbatioVault::K_doc::v1
ProbatioVault::K_encryption::v1 Inchangé (déjà correct)
N/A ProbatioVault::K_auth::v1 (nouveau)

3. Garantir l'interopérabilité iOS/backend

Le label ProbatioVault::K_auth::v1 doit être identique sur : - ProbatioVault-app (React Native / iOS) - ProbatioVault-backend (NestJS)

L'interopérabilité sera validée via des vecteurs de test RFC 5869 communs.


Critères d'acceptation préliminaires

ID Critère Mesurable
CA-01 deriveAuthKey(kMaster) retourne une clé de 32 bytes Jest assertion
CA-02 Le label utilisé est exactement ProbatioVault::K_auth::v1 Code review
CA-03 Dérivation déterministe : même K_master → même K_auth Test avec vecteurs
CA-04 K_auth !== K_encryption !== K_doc pour le même K_master Test d'isolation
CA-05 Label Kdoc corrigé en K_doc dans hkdf.ts Grep + tests
CA-06 Aucune régression sur les fonctions existantes (K_encryption, K_doc, K_share) Tests unitaires
CA-07 Constants centralisées utilisées (pas de redéfinition inline) Code review

Dépendances

Story Statut Relation
PD-34 DONE (anomaly) Correction anomalie info string
PD-97 DONE Consumer de K_auth (crypto iOS)
PD-24/25 DONE SRP-6a backend (consommera K_auth)

Risques identifiés

Risque Impact Mitigation
Régression K_doc si label modifié CRITIQUE Vecteurs de test avant/après, migration si données existantes
Incompatibilité backend si label différent MAJEUR Définir constants partagées, tests d'intégration
Hermes limitations (WebAssembly) MINEUR @noble/hashes pure JS, pas de WASM

Hors périmètre

  • Migration des données existantes (K_doc dérivé avec ancien label)
  • Modification de l'authentification SRP-6a backend
  • Implémentation backend de K_auth (story séparée si nécessaire)

Notes techniques

Hiérarchie HKDF complète après PD-243

// constants.ts (centralisé)
export const HKDF_CONTEXTS = {
  K_ENCRYPTION: "ProbatioVault::K_encryption::v1",
  K_AUTH: "ProbatioVault::K_auth::v1",        // ← NOUVEAU
  K_SHARE: "ProbatioVault::K_share::v1",
  K_DOC: "ProbatioVault::K_doc::v1",          // ← CORRIGÉ (était Kdoc)
} as const;

Fonction cible

// hkdf.ts
export async function deriveAuthKey(kMaster: Uint8Array): Promise<Uint8Array> {
  if (kMaster?.length !== 32) {
    throw new Error("K_master must be exactly 32 bytes");
  }

  const info = new TextEncoder().encode(HKDF_CONTEXTS.K_AUTH);
  return hkdf(sha3_256, kMaster, new Uint8Array(0), info, 32);
}

Validation PO

  • Besoin compris et validé
  • Périmètre acceptable
  • Risques acceptés