Aller au contenu

🔄 Migration V4 - Argon2id + HKDF-SHA3-256

Contexte

La version V4 de l'architecture cryptographique ProbatioVault introduit :

  1. Argon2id pour la dérivation K_encryption (remplace PBKDF2-SHA256)
  2. HKDF-SHA3-256 pour la dérivation de clés spécifiques
  3. SHA3-256 pour le hash probatoire des documents (conforme PD-38)

Pourquoi migrer ?

Critère V3 (PBKDF2) V4 (Argon2id) Gain
Résistance GPU/ASIC Faible (itérations CPU) Forte (memory-hard) ✅ 1000x
Coût attaque $0.00001/million hash $10+/million hash ✅ 1,000,000x
Conformité OWASP Déprécié First choice 2024
Durabilité 20-50 ans Questionable Garantie
Résistance quantique (hash) SHA-256 (vulnérable) SHA3-256 (résistant)

📋 Checklist de migration

Utilisateurs existants (PRODUCTION)

⚠️ Aucun utilisateur en DEV actuellement → Migration directe sans backward compatibility.

Si des utilisateurs existaient :

  • Communiquer changement aux utilisateurs (délai ~500ms au login)
  • Activer migration automatique au prochain login
  • Surveiller logs migration (Migration V3 → V4 détectée)
  • Vérifier aucun échec de migration (fallback V3 si erreur)
  • Nettoyer anciennes keystores après migration réussie

Développement (ACTUEL)

  • Installer dépendances (@noble/hashes, argon2-browser)
  • Créer service keyDerivation.ts (Argon2id)
  • Créer service hkdf.ts (HKDF-SHA3-256)
  • Intégrer dans crypto.ts (V4 support)
  • Mettre à jour computeFileHash() (SHA3-256)
  • Créer tests unitaires
  • Créer documentation

Tests & Validation

  • Exécuter tests unitaires (npm test)
  • Tester migration manuelle V2 → V4
  • Tester migration manuelle V3 → V4
  • Vérifier rotation password (crée V4)
  • Benchmark Argon2id sur devices (iPhone 8, 12, 15)
  • Vérifier hash probatoire (SHA3-256 NIST vectors)

🔧 Modifications techniques

1. Dependencies (package.json)

{
  "dependencies": {
    "@noble/hashes": "1.5.0",
    "argon2-browser": "1.18.0"
  }
}

2. Keystore V4 Schema

Avant (V3) :

type KeystoreV3 = {
  v: "pv-keystore-v3";
  kdf: { alg: "PBKDF2-SHA256"; salt: string; iter: number };
  encMaster: { iv: string; ct: string; tag: string };
};

Après (V4) :

type KeystoreV4 = {
  v: "pv-keystore-v4";
  kdf: { alg: "Argon2id"; salt: string }; // Pas d'iter (params hardcodés)
  encMaster: { iv: string; ct: string; tag: string };
};

3. Hash probatoire (PD-38)

Avant (V3) :

// SHA-256 (expo-crypto)
const hash = await Crypto.digestStringAsync(
  Crypto.CryptoDigestAlgorithm.SHA256,
  base64Content
);

Après (V4) :

// SHA3-256 (@noble/hashes)
import { sha3_256 } from '@noble/hashes/sha3';

const bytes = b64ToBuf(base64Content);
const hashBytes = sha3_256(bytes);
const hash = Array.from(hashBytes)
  .map(b => b.toString(16).padStart(2, '0'))
  .join('');

4. Migration automatique

Flux au login :

export async function ensureMasterKey(password: string): Promise<Uint8Array> {
  const existing = await loadKeystore();

  if (existing) {
    const key = await decryptMasterKey(existing, password);

    // Migration automatique V2/V3 → V4
    if (existing.v === "pv-keystore-v2" || existing.v === "pv-keystore-v3") {
      console.log(`🔄 Migration ${existing.v} → V4 (Argon2id)...`);
      await migrateKeystoreToV4(password, key);
    }

    return key;
  }

  // Nouveau compte → V4 directement
  // ... (création keystore V4)
}

📊 Comparaison performances

Login time (Argon2id vs PBKDF2)

Device PBKDF2 (100k iter) Argon2id (64 MiB) Delta
iPhone 15 Pro ~150ms ~300ms +150ms
iPhone 12 ~200ms ~500ms +300ms
iPhone 8 ~400ms ~800ms +400ms

Verdict : Acceptable pour un coffre-fort probatoire (+300-400ms).

Hash computation (SHA3-256 vs SHA-256)

File size SHA-256 SHA3-256 Delta
100 KB ~5ms ~8ms +3ms
1 MB ~30ms ~40ms +10ms
10 MB ~250ms ~350ms +100ms

Verdict : Conforme PD-38 (< 50ms pour 1 MB). ✅


🧪 Tests de migration

Test 1 : Migration V3 → V4

describe('Migration V3 → V4', () => {
  it('should migrate keystore on login', async () => {
    // 1. Créer keystore V3
    const password = 'TestPassword123!';
    const ksV3 = await createV3Keystore(password);
    await SecureStore.setItemAsync('pv_keystore_v3', JSON.stringify(ksV3));

    // 2. Login (déclenche migration)
    const kMaster = await ensureMasterKey(password);

    // 3. Vérifier V4 créée
    const ksV4Raw = await SecureStore.getItemAsync('pv_keystore_v4');
    const ksV4 = JSON.parse(ksV4Raw);

    expect(ksV4.v).toBe('pv-keystore-v4');
    expect(ksV4.kdf.alg).toBe('Argon2id');
  });
});

Test 2 : Hash probatoire SHA3-256

describe('SHA3-256 NIST Test Vectors', () => {
  it('should match NIST FIPS 202 vector', async () => {
    const input = 'abc';
    const expected = '3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532';

    const bytes = new TextEncoder().encode(input);
    const base64 = bufToB64(bytes);
    const hash = await computeFileHash(base64);

    expect(hash).toBe(expected);
  });
});

🚨 Rollback plan

En cas de problème critique en production (utilisateurs existants) :

Option 1 : Rollback code

# 1. Revert commit V4
git revert <commit-v4>

# 2. Redéployer V3
npm run build
npx eas-cli build --platform ios

# 3. Utilisateurs déjà migrés → bloqués (incompatible)
# → Nécessite support client

Option 2 : Support dual V3/V4

// Désactiver migration automatique
export async function ensureMasterKey(password: string): Promise<Uint8Array> {
  const existing = await loadKeystore();

  if (existing) {
    const key = await decryptMasterKey(existing, password);

    // ⚠️ ROLLBACK: Ne plus migrer automatiquement
    // if (existing.v === "pv-keystore-v2" || existing.v === "pv-keystore-v3") {
    //   await migrateKeystoreToV4(password, key);
    // }

    return key;
  }

  // Nouveau compte → V3 (au lieu de V4)
  // ... (créer V3 au lieu de V4)
}

📈 Métriques de succès

KPIs post-migration

  • Taux de migration : 100% des utilisateurs migrés sous 7 jours
  • Échecs migration : < 0.1% (logs [V4 GCM] Échec déchiffrement)
  • Performance login : < 1s (p95) sur iPhone 12+
  • Hash probatoire : 100% conformité NIST FIPS 202
  • Détection doublons : 0 collision hash SHA3-256

Monitoring

// Analytics events
analytics.track('crypto_migration_started', {
  from: existing.v,
  to: 'pv-keystore-v4',
  device: deviceInfo,
});

analytics.track('crypto_migration_completed', {
  from: existing.v,
  to: 'pv-keystore-v4',
  duration_ms: migrationTime,
});

analytics.track('crypto_migration_failed', {
  from: existing.v,
  to: 'pv-keystore-v4',
  error: error.message,
});

🔗 Ressources

Documentation

Standards

Support


Date migration : 2025-01-16 Version : V4 (Argon2id + HKDF-SHA3-256) Statut : ✅ Déployée en DEV