Hiérarchie des clés¶
Dérivation hiérarchique des clés cryptographiques
Architecture V4 (Argon2id + HKDF-SHA3-256)¶
Password (utilisateur)
↓
[Argon2id v1.3] ← PD-33 : derivePassword()
↓
K_encryption (32 bytes)
↓
[AES-256-GCM]
↓
K_master_user (32 bytes, stocké chiffré dans keystore local)
↓
[HKDF-SHA3-256] ← PD-34 : deriveDocumentKey()
↓
K_doc_1 (32 bytes, unique par document)
K_doc_2 (32 bytes, unique par document)
K_doc_3 (32 bytes, unique par document)
...
Dérivation¶
Étape 1 : K_encryption (PD-33)¶
Fonction : derivePassword(password, salt_user) → K_encryption
Algorithme : Argon2id v1.3 (RFC 9106)
Paramètres : - Memory : 64 MiB (65536 KiB) - Iterations : 3 - Parallelism : 4 - Salt : 16 bytes (unique par utilisateur, CSPRNG) - Output : 32 bytes - Associated Data : "ProbatioVault_Encryption_v1"
Implémentation :
K_encryption = Argon2id(
password,
salt_user,
memory: 64 MiB,
iterations: 3,
parallelism: 4,
hashLen: 32,
associated_data: "ProbatioVault_Encryption_v1"
)
Usage : Chiffre K_master_user dans le keystore V4 local (SecureStore)
Étape 2 : K_master_user (stockage)¶
Chiffrement : K_master_user est chiffré avec K_encryption via AES-256-GCM
Keystore V4 :
{
"v": "pv-keystore-v4",
"kdf": {
"alg": "Argon2id",
"salt": "base64..."
},
"encMaster": {
"iv": "base64...",
"ct": "base64...",
"tag": "base64..."
}
}
Stockage : SecureStore iOS/Android (chiffré OS-level + Argon2id)
Étape 3 : K_doc (PD-34)¶
Fonction : deriveDocumentKey(K_master_user, doc_id) → K_doc
Algorithme : HKDF-SHA3-256 (RFC 5869 avec SHA3-256)
Paramètres : - IKM : K_master_user (32 bytes) - Salt : UUID document converti en bytes (16 bytes) - Info : "ProbatioVault_Document_v1" || doc_id_bytes - Output : 32 bytes
Implémentation :
// Extraction
PRK = HMAC-SHA3-256(salt=doc_id_bytes, ikm=K_master_user)
// Expansion
K_doc = HKDF-Expand(
PRK,
info: "ProbatioVault_Document_v1" || doc_id_bytes,
length: 32
)
Usage : Chiffre chaque document avec sa propre clé unique (AES-256-GCM)
Propriétés de sécurité¶
1. Zero-Knowledge¶
- ✅ Serveur ne voit jamais :
password,K_encryption,K_master_user,K_doc - ✅ Serveur stocke seulement : Documents chiffrés, hash probatoires SHA3-256
- ✅ Authentification SRP-6a : Preuve de connaissance sans transmission password
2. Résistance attaques¶
| Attaque | Protection | Mécanisme |
|---|---|---|
| GPU/ASIC | ✅ Forte | Argon2id memory-hard (64 MiB) |
| Rainbow tables | ✅ Forte | Salt unique 16 bytes par utilisateur |
| Timing attacks | ✅ Forte | Argon2id hybride (résistant timing) |
| Brute force | ✅ Forte | ~500ms/essai (64 MiB + 3 iter) |
| Quantum (hash) | ✅ Résistant | SHA3-256 (NIST post-quantum) |
3. Isolation cryptographique¶
- ✅ Chaque document : Clé unique dérivée de son UUID
- ✅ Domain separation : Associated Data distinctes (Encryption_v1, Document_v1)
- ✅ Révocation granulaire : Supprimer K_doc sans affecter autres documents
4. Forward secrecy¶
- ✅ Rotation password : Nouveau salt → nouvelle K_encryption
- ✅ Nouveau device : Nouveau keystore → nouvelles clés dérivées
- ✅ Perte device : K_master_user inaccessible (chiffré par password)
Migrations¶
V2 → V4 (PBKDF2 → Argon2id)¶
Migration automatique au premier unlock :
// 1. Unlock avec PBKDF2-SHA256 (100k iterations)
K_master_v2 = PBKDF2-SHA256(password, salt_v2, 100000)
// 2. Déchiffrement K_master avec K_master_v2
K_master_user = AES-CBC-Decrypt(K_master_v2, encMaster_v2)
// 3. Re-chiffrement avec Argon2id
salt_v4 = random(16)
K_encryption_v4 = Argon2id(password, salt_v4, ...)
encMaster_v4 = AES-GCM-Encrypt(K_encryption_v4, K_master_user)
// 4. Sauvegarde keystore V4
SecureStore.setItem("pv_keystore_v4", keystore_v4)
Performance : Migration transparente, ~1s (une seule fois)
Benchmarks¶
Dérivation K_encryption (Argon2id)¶
| Device | RAM | Durée | Expérience |
|---|---|---|---|
| iPhone 15 Pro | 8 GB | ~400 ms | ⚡ Excellent |
| iPhone 12 | 4 GB | ~500 ms | ✅ Bon |
| iPhone 8 | 2 GB | ~700 ms | ⚠️ Acceptable |
Dérivation K_doc (HKDF-SHA3-256)¶
| Opération | Durée | Impact UX |
|---|---|---|
| 1 document | ~1 ms | Imperceptible |
| 100 documents | ~100 ms | Négligeable |
| 1000 documents | ~1 s | Acceptable (batch) |
Standards et conformité¶
| Standard | Version | Conformité |
|---|---|---|
| RFC 9106 | Argon2 v1.3 | ✅ K_encryption |
| RFC 5869 | HKDF | ✅ K_doc (avec SHA3-256) |
| NIST FIPS 202 | SHA3-256 | ✅ Hash + HKDF |
| OWASP ASVS | 4.0 (2024) | ✅ 64 MiB minimum |
| NIST SP 800-63B | Rev. 3 | ✅ Memory-hard KDF |
Références¶
- PD-33 : Dérivation Password avec Argon2id
- PD-34 : Dérivation K_doc avec HKDF-SHA3-256
- PD-38 : Hash probatoire SHA3-256