/Argon2

Argon2

Créé en 2015 • PHC WinnerAlex Biryukov et équipe

Champion 2024 - Standard ModerneMemory-hardGPU/ASIC resistant
PHC 2015
Winner Competition

🏆 CHAMPION ABSOLU 2024 - ÉTAT DE L'ART CRYPTOGRAPHIQUE

Argon2 domine l'écosystème moderne des algorithmes de hachage de mots de passe. Winner de la Password Hashing Competition 2015, résistance maximale GPU/ASIC, configuration adaptive et adoption massive par les frameworks modernes.

Variants Argon2 - Architecture Adaptative

VariantSécurité SpécialiséePerformanceUsage Recommandé
Argon2iSide-channel résistantBonneEnvironnements non-sécurisés
Argon2dGPU/ASIC résistantExcellenteServeurs sécurisés
Argon2idHybride optimalTrès bonneRECOMMANDÉ - Usage général
Recommandation 2024 : Argon2id

Argon2id combine le meilleur des deux mondes : sécurité side-channel d'Argon2i et résistance GPU/ASIC d'Argon2d. Premier choix pour toutes nouvelles implémentations.

Guide Configuration Production

Cas d'UsageMémoireTempsParallélismeDurée Cible
Web Interactif64 MiB21~200ms
API Backend256 MiB34~500ms
Haute Sécurité1 GiB58~2000ms
Mobile/IoT32 MiB21~150ms
Enterprise512 MiB416~1000ms
Memory Cost

Détermine la résistance GPU/ASIC. 64 MiB minimum, 1 GiB+ pour haute sécurité.

Time Cost

Nombre d'itérations. Équilibre sécurité/performance. 2-5 selon contexte.

Parallelism

Threads simultanés. Améliore performance sans compromettre la sécurité.

Avantages Sécuritaires Révolutionnaires

Résistance GPU/ASIC

Maximum

Memory-hard function avec accès mémoire intensifs et imprévisibles

Configuration Flexible

Excellent

Paramètres ajustables : mémoire, temps, parallélisme selon besoin

Sécurité Side-Channel

Important

Argon2i/id résistants aux attaques cache-timing

Champion PHC 2015

Référence

Validation académique rigoureuse, adoption industrielle croissante

Résistances Multi-Niveaux

🛡️ Résistance Matérielle
  • • GPU : Memory-hard → coût prohibitif
  • • ASIC : Accès mémoire → goulot étranglement
  • • Parallélisme : Limité par synchronisation
  • • Architecture : Favorise processeurs généralistes
🔐 Résistance Logicielle
  • • Side-channel : Argon2i/id protection
  • • Cache timing : Accès mémoire masqués
  • • Brute force : Configuration adaptive
  • • Rainbow tables : Sel unique + iteration

Adoption Moderne et Cas d'Usage

Applications Modernes

Web apps nouvelles générations
APIs RESTful haute sécurité
Applications mobiles premium
SaaS et cloud services
Microservices authentication

Finance & Fintech

Crypto-monnaies exchanges
Banking mobile apps
Payment processing
Investment platforms
DeFi protocols

Enterprise Security

Active Directory moderne
SSO et identity providers
PAM solutions
Zero-trust architectures
Compliance frameworks

IoT & Edge Computing

Industrial IoT security
Smart home devices
Edge computing nodes
Embedded systems
5G network functions
Adoption Industrielle 2024
Django 4.2+
Python framework
Symfony 6+
PHP framework
Spring 6+
Java ecosystem
Node.js
Modern ecosystem

Implémentations Production-Ready

Code Champion - Standards 2024

Implémentations complètes avec configuration adaptive, monitoring enterprise et optimisations performance pour usage production intensive.

Node.js - Manager Argon2id Adaptatif

const argon2 = require('argon2');

// ✅ ARGON2 - Configuration Recommandée 2024
class Argon2Manager {
  constructor() {
    // Configuration optimale sécurité/performance
    this.config = {
      type: argon2.argon2id,        // Variant hybride recommandé
      memoryCost: 2 ** 16,          // 64 MiB de mémoire
      timeCost: 3,                  // 3 iterations
      parallelism: 1,               // 1 thread (ajuster selon CPU)
      hashLength: 32,               // 32 bytes sortie
      saltLength: 32                // 32 bytes salt
    };
  }

  // Hash sécurisé mot de passe
  async hashPassword(password) {
    try {
      const hash = await argon2.hash(password, this.config);
      return {
        hash: hash,
        algorithm: 'Argon2id',
        config: this.config,
        timestamp: new Date().toISOString(),
        security: 'MAXIMUM_2024'
      };
    } catch (error) {
      throw new Error(`Argon2 hashing failed: ${error.message}`);
    }
  }

  // Vérification sécurisée
  async verifyPassword(password, hash) {
    try {
      const isValid = await argon2.verify(hash, password);
      return {
        valid: isValid,
        algorithm: 'Argon2id',
        timingResistant: true
      };
    } catch (error) {
      throw new Error(`Argon2 verification failed: ${error.message}`);
    }
  }

  // Configuration adaptative selon usage
  getConfigForUsage(usage) {
    const configs = {
      // Applications web interactives
      interactive: {
        type: argon2.argon2id,
        memoryCost: 2 ** 16,      // 64 MiB
        timeCost: 2,              // 2 iterations (~150ms)
        parallelism: 1
      },
      
      // Applications serveur backend
      server: {
        type: argon2.argon2id,
        memoryCost: 2 ** 18,      // 256 MiB
        timeCost: 3,              // 3 iterations (~500ms)
        parallelism: 4
      },
      
      // Sécurité maximale
      maximum: {
        type: argon2.argon2id,
        memoryCost: 2 ** 20,      // 1 GiB
        timeCost: 5,              // 5 iterations (~2s)
        parallelism: 8
      }
    };
    
    return configs[usage] || configs.interactive;
  }

  // Benchmark pour optimiser configuration
  async benchmark(password = 'testpassword', configs = ['interactive', 'server', 'maximum']) {
    const results = {};
    
    for (const configName of configs) {
      const config = this.getConfigForUsage(configName);
      const start = process.hrtime.bigint();
      
      try {
        await argon2.hash(password, config);
        const end = process.hrtime.bigint();
        const durationMs = Number(end - start) / 1000000;
        
        results[configName] = {
          config: config,
          duration: `${durationMs.toFixed(0)}ms`,
          memoryMB: config.memoryCost / 1024,
          recommendation: this.getRecommendation(durationMs)
        };
      } catch (error) {
        results[configName] = { error: error.message };
      }
    }
    
    return results;
  }

  getRecommendation(durationMs) {
    if (durationMs < 100) return 'Trop rapide - augmenter paramètres';
    if (durationMs < 500) return 'Bon pour applications interactives';
    if (durationMs < 1000) return 'Bon pour backend services';
    if (durationMs < 2000) return 'Haute sécurité acceptable';
    return 'Très sécurisé - vérifier UX';
  }
}

// Usage Production
const argon2Manager = new Argon2Manager();

// Hash mot de passe
(async () => {
  const password = 'MonMotDePasseSecurise2024!';
  
  // Hash
  const result = await argon2Manager.hashPassword(password);
  console.log('Hash Result:', result);
  
  // Vérification
  const verification = await argon2Manager.verifyPassword(password, result.hash);
  console.log('Verification:', verification);
  
  // Benchmark configurations
  const benchmark = await argon2Manager.benchmark();
  console.log('Benchmark:', benchmark);
})();

Python - Configuration Multi-Profils

import argon2
import secrets
import time
from typing import Optional, Dict, Any

class Argon2Manager:
    """Manager Argon2 optimisé pour production Python"""
    
    def __init__(self):
        # Configuration recommandée 2024
        self.hasher = argon2.PasswordHasher(
            time_cost=3,          # 3 iterations
            memory_cost=65536,    # 64 MiB (2^16 KiB)
            parallelism=1,        # 1 thread
            hash_len=32,          # 32 bytes output
            salt_len=32,          # 32 bytes salt
            encoding='utf-8'
        )
        
        # Configurations prédéfinies
        self.configs = {
            'interactive': argon2.PasswordHasher(
                time_cost=2, memory_cost=65536, parallelism=1
            ),
            'server': argon2.PasswordHasher(
                time_cost=3, memory_cost=262144, parallelism=4  # 256 MiB
            ),
            'maximum': argon2.PasswordHasher(
                time_cost=5, memory_cost=1048576, parallelism=8  # 1 GiB
            )
        }
    
    def hash_password(self, password: str, config: str = 'default') -> Dict[str, Any]:
        """Hash sécurisé avec Argon2id"""
        hasher = self.configs.get(config, self.hasher)
        
        start_time = time.perf_counter()
        
        try:
            hash_result = hasher.hash(password)
            duration = time.perf_counter() - start_time
            
            return {
                'hash': hash_result,
                'algorithm': 'Argon2id',
                'variant': 'argon2id',
                'duration': f"{duration*1000:.0f}ms",
                'config': config,
                'security_level': 'MAXIMUM',
                'timestamp': time.time()
            }
            
        except argon2.exceptions.HashingError as e:
            raise Exception(f"Argon2 hashing failed: {e}")
    
    def verify_password(self, password: str, hash_value: str) -> Dict[str, Any]:
        """Vérification sécurisée temps constant"""
        start_time = time.perf_counter()
        
        try:
            # Vérification avec timing constant
            is_valid = self.hasher.verify(hash_value, password)
            duration = time.perf_counter() - start_time
            
            return {
                'valid': is_valid,
                'algorithm': 'Argon2id',
                'duration': f"{duration*1000:.2f}ms",
                'timing_safe': True
            }
            
        except argon2.exceptions.VerifyMismatchError:
            # Maintenir temps constant même pour échecs
            time.sleep(max(0, 0.1 - (time.perf_counter() - start_time)))
            return {
                'valid': False,
                'algorithm': 'Argon2id',
                'timing_safe': True
            }
        except Exception as e:
            raise Exception(f"Argon2 verification failed: {e}")
    
    def needs_rehash(self, hash_value: str, config: str = 'default') -> bool:
        """Vérifie si le hash doit être mis à jour"""
        hasher = self.configs.get(config, self.hasher)
        try:
            return hasher.check_needs_rehash(hash_value)
        except:
            return True  # En cas d'erreur, recommander rehash
    
    def benchmark_configurations(self, test_password: str = 'benchmark123') -> Dict[str, Any]:
        """Benchmark des différentes configurations"""
        results = {}
        
        for config_name, hasher in self.configs.items():
            start_time = time.perf_counter()
            
            try:
                hasher.hash(test_password)
                duration = (time.perf_counter() - start_time) * 1000
                
                results[config_name] = {
                    'duration_ms': round(duration),
                    'memory_mb': hasher.memory_cost // 1024,
                    'time_cost': hasher.time_cost,
                    'parallelism': hasher.parallelism,
                    'recommendation': self._get_recommendation(duration)
                }
                
            except Exception as e:
                results[config_name] = {'error': str(e)}
        
        return results
    
    def _get_recommendation(self, duration_ms: float) -> str:
        """Recommandations basées sur la durée"""
        if duration_ms < 100:
            return "⚠️  Trop rapide - augmenter paramètres"
        elif duration_ms < 500:
            return "✅ Optimal pour applications interactives"
        elif duration_ms < 1000:
            return "✅ Bon pour services backend"
        elif duration_ms < 2000:
            return "🔒 Haute sécurité - acceptable"
        else:
            return "🔒 Très sécurisé - vérifier impact UX"
    
    def memory_usage_estimate(self, config: str = 'default') -> Dict[str, Any]:
        """Estimation usage mémoire"""
        hasher = self.configs.get(config, self.hasher)
        
        memory_kb = hasher.memory_cost
        memory_mb = memory_kb // 1024
        
        return {
            'config': config,
            'memory_kb': memory_kb,
            'memory_mb': memory_mb,
            'parallelism': hasher.parallelism,
            'total_memory_mb': memory_mb * hasher.parallelism,
            'concurrent_users_estimate': max(1, 1000 // memory_mb)
        }

# Usage Production
if __name__ == "__main__":
    manager = Argon2Manager()
    
    # Test complet
    password = "MotDePasseSecurise2024!"
    
    # Hash
    hash_result = manager.hash_password(password, 'interactive')
    print(f"Hash: {hash_result}")
    
    # Vérification
    verify_result = manager.verify_password(password, hash_result['hash'])
    print(f"Verification: {verify_result}")
    
    # Vérifier si rehash nécessaire
    needs_rehash = manager.needs_rehash(hash_result['hash'], 'server')
    print(f"Needs rehash: {needs_rehash}")
    
    # Benchmark
    benchmark = manager.benchmark_configurations()
    print("Benchmark results:")
    for config, result in benchmark.items():
        print(f"  {config}: {result}")
    
    # Usage mémoire
    memory = manager.memory_usage_estimate('server')
    print(f"Memory usage: {memory}")

Système Enterprise Adaptatif avec Monitoring

// Système Argon2 Enterprise avec Monitoring
// Production-ready avec adaptive tuning et compliance

class EnterpriseArgon2System {
  constructor(options = {}) {
    this.argon2 = require('argon2');
    
    // Configurations adaptatives
    this.profiles = {
      web_interactive: {
        type: this.argon2.argon2id,
        memoryCost: 2 ** 16,    // 64 MiB
        timeCost: 2,            // ~150-200ms
        parallelism: 1,
        target_time_ms: 200
      },
      
      api_backend: {
        type: this.argon2.argon2id,
        memoryCost: 2 ** 18,    // 256 MiB
        timeCost: 3,            // ~400-600ms
        parallelism: 4,
        target_time_ms: 500
      },
      
      high_security: {
        type: this.argon2.argon2id,
        memoryCost: 2 ** 20,    // 1 GiB
        timeCost: 5,            // ~1500-2500ms
        parallelism: 8,
        target_time_ms: 2000
      }
    };
    
    // Métriques et monitoring
    this.metrics = {
      total_hashes: 0,
      total_verifications: 0,
      avg_hash_time: 0,
      avg_verify_time: 0,
      memory_peak_mb: 0,
      errors: 0,
      adaptive_adjustments: 0
    };
    
    // Configuration adaptive
    this.adaptive = {
      enabled: options.adaptive || true,
      target_time_ms: options.target_time_ms || 300,
      adjustment_threshold: options.adjustment_threshold || 0.3,
      min_memory_cost: 2 ** 15,  // 32 MiB minimum
      max_memory_cost: 2 ** 22   // 4 GiB maximum
    };
    
    this.current_profile = options.profile || 'api_backend';
    this.compliance_mode = options.compliance || false;
    
    // Auto-tuning initial
    if (this.adaptive.enabled) {
      this.initializeAdaptiveTuning();
    }
  }

  async hashPassword(password, options = {}) {
    const startTime = performance.now();
    const profile = options.profile || this.current_profile;
    
    try {
      // Validation sécurité
      this.validatePassword(password);
      
      // Configuration active
      const config = this.getCurrentConfig(profile);
      
      // Hash avec monitoring
      const hash = await this.argon2.hash(password, config);
      const duration = performance.now() - startTime;
      
      // Mise à jour métriques
      this.updateHashMetrics(duration, config.memoryCost);
      
      // Ajustement adaptatif
      if (this.adaptive.enabled) {
        await this.adjustConfigIfNeeded(duration, profile);
      }
      
      // Résultat avec metadata
      const result = {
        hash: hash,
        algorithm: 'Argon2id',
        profile: profile,
        config: config,
        performance: {
          duration_ms: Math.round(duration),
          memory_mb: config.memoryCost / 1024,
          threads: config.parallelism
        },
        compliance: this.compliance_mode ? this.getComplianceInfo() : undefined,
        timestamp: new Date().toISOString()
      };
      
      // Audit log
      this.auditLog('HASH_CREATED', { profile, duration, memory_mb: config.memoryCost / 1024 });
      
      return result;
      
    } catch (error) {
      this.metrics.errors++;
      this.auditLog('HASH_ERROR', { error: error.message, profile });
      throw new Error(`Argon2 hash failed: ${error.message}`);
    }
  }

  async verifyPassword(password, hash, options = {}) {
    const startTime = performance.now();
    
    try {
      // Vérification avec protection timing
      const isValid = await this.argon2.verify(hash, password);
      const duration = performance.now() - startTime;
      
      // Mise à jour métriques
      this.updateVerifyMetrics(duration);
      
      // Check si rehash recommandé
      const needsRehash = await this.checkRehashNeeded(hash);
      
      const result = {
        valid: isValid,
        algorithm: 'Argon2id',
        verification_time_ms: Math.round(duration),
        needs_rehash: needsRehash,
        timing_safe: true
      };
      
      // Audit
      this.auditLog('VERIFY_ATTEMPT', { 
        valid: isValid, 
        duration, 
        needs_rehash: needsRehash 
      });
      
      return result;
      
    } catch (error) {
      this.metrics.errors++;
      this.auditLog('VERIFY_ERROR', { error: error.message });
      
      // Timing constant même en cas d'erreur
      const minTime = 100;
      const elapsed = performance.now() - startTime;
      if (elapsed < minTime) {
        await new Promise(resolve => setTimeout(resolve, minTime - elapsed));
      }
      
      return { valid: false, error: error.message, timing_safe: true };
    }
  }

  // Auto-tuning adaptatif
  async adjustConfigIfNeeded(actualDuration, profile) {
    const targetTime = this.profiles[profile].target_time_ms;
    const threshold = this.adaptive.adjustment_threshold;
    
    const ratio = actualDuration / targetTime;
    
    if (ratio < (1 - threshold) || ratio > (1 + threshold)) {
      await this.adjustProfile(profile, ratio);
      this.metrics.adaptive_adjustments++;
    }
  }

  async adjustProfile(profile, ratio) {
    const currentConfig = this.profiles[profile];
    
    if (ratio > 1.2) {
      // Trop lent - réduire charge
      if (currentConfig.memoryCost > this.adaptive.min_memory_cost) {
        currentConfig.memoryCost = Math.max(
          this.adaptive.min_memory_cost,
          Math.floor(currentConfig.memoryCost * 0.8)
        );
      } else if (currentConfig.timeCost > 1) {
        currentConfig.timeCost = Math.max(1, currentConfig.timeCost - 1);
      }
    } else if (ratio < 0.8) {
      // Trop rapide - augmenter sécurité
      if (currentConfig.memoryCost < this.adaptive.max_memory_cost) {
        currentConfig.memoryCost = Math.min(
          this.adaptive.max_memory_cost,
          Math.floor(currentConfig.memoryCost * 1.25)
        );
      } else {
        currentConfig.timeCost = Math.min(10, currentConfig.timeCost + 1);
      }
    }
    
    this.auditLog('CONFIG_ADJUSTED', { 
      profile, 
      ratio: ratio.toFixed(2), 
      new_config: currentConfig 
    });
  }

  // Monitoring et métriques
  updateHashMetrics(duration, memoryCost) {
    this.metrics.total_hashes++;
    this.metrics.avg_hash_time = (
      this.metrics.avg_hash_time * (this.metrics.total_hashes - 1) + duration
    ) / this.metrics.total_hashes;
    
    const memoryMB = memoryCost / 1024;
    this.metrics.memory_peak_mb = Math.max(this.metrics.memory_peak_mb, memoryMB);
  }

  updateVerifyMetrics(duration) {
    this.metrics.total_verifications++;
    this.metrics.avg_verify_time = (
      this.metrics.avg_verify_time * (this.metrics.total_verifications - 1) + duration
    ) / this.metrics.total_verifications;
  }

  getSystemMetrics() {
    const uptime = process.uptime();
    
    return {
      uptime_seconds: Math.floor(uptime),
      total_operations: this.metrics.total_hashes + this.metrics.total_verifications,
      operations_per_second: (this.metrics.total_hashes + this.metrics.total_verifications) / uptime,
      average_hash_time_ms: Math.round(this.metrics.avg_hash_time),
      average_verify_time_ms: Math.round(this.metrics.avg_verify_time),
      memory_peak_mb: this.metrics.memory_peak_mb,
      adaptive_adjustments: this.metrics.adaptive_adjustments,
      error_rate: (this.metrics.errors / (this.metrics.total_hashes + this.metrics.total_verifications) * 100).toFixed(3) + '%',
      current_configs: this.profiles
    };
  }

  // Conformité et audit
  getComplianceInfo() {
    return {
      algorithm: 'Argon2id',
      phc_winner: '2015',
      resistance: ['GPU', 'ASIC', 'Side-channel', 'Parallel'],
      certification: 'PHC Winner - Industry Standard',
      memory_hard: true,
      quantum_resistant: 'Partially (brute-force protection)',
      recommended_by: ['OWASP', 'NIST', 'RFC-9106']
    };
  }

  auditLog(action, details) {
    const logEntry = {
      timestamp: new Date().toISOString(),
      action: action,
      algorithm: 'Argon2id',
      details: details,
      system_state: {
        total_operations: this.metrics.total_hashes + this.metrics.total_verifications,
        current_profile: this.current_profile,
        adaptive_enabled: this.adaptive.enabled
      }
    };
    
    console.log('ARGON2_AUDIT:', JSON.stringify(logEntry));
  }

  // Utilitaires
  validatePassword(password) {
    if (!password || typeof password !== 'string') {
      throw new Error('Password must be a non-empty string');
    }
    if (password.length > 4096) {
      throw new Error('Password too long (max 4096 characters)');
    }
  }

  getCurrentConfig(profile) {
    return { ...this.profiles[profile] };
  }

  async checkRehashNeeded(hash) {
    try {
      // Logique pour déterminer si rehash nécessaire
      // (ex: configuration changée, sécurité améliorée)
      return false; // Simplifié pour l'exemple
    } catch {
      return true; // En cas d'erreur, recommander rehash
    }
  }
}

// Usage Enterprise
const argon2System = new EnterpriseArgon2System({
  adaptive: true,
  profile: 'api_backend',
  compliance: true,
  target_time_ms: 300
});

// Monitoring en temps réel
setInterval(() => {
  const metrics = argon2System.getSystemMetrics();
  console.log('System Metrics:', metrics);
}, 60000); // Chaque minute

⚡ Points Clés Implémentation

🔧 Configuration Adaptive
  • • Auto-tuning selon performance cible
  • • Profils prédéfinis par cas d'usage
  • • Monitoring temps réel
  • • Ajustement dynamique charge
🚀 Optimisations
  • • Parallélisation intelligente
  • • Gestion mémoire optimisée
  • • Cache des configurations
  • • Métriques enterprise détaillées

Actions Rapides

Métriques Champion

PHC Position1st 🏆
Résistance GPUMaximum
Résistance ASICExcellente
Side-channel (id)Résistant
ConfigurationFlexible
Champion

Argon2 est le standard de facto pour 2024 et au-delà. Adopté massivement par l'industrie moderne.

Ressources et Documentation PHC

RFC 9106
Standard IETF Argon2
PHC Competition
Password Hashing Competition
Argon2 Paper
Paper académique original
GitHub Official
Implémentation référence C
OWASP Guide
Recommandations OWASP
Node.js argon2
Package Node.js officiel

Argon2 : L'Avenir du Hachage de Mots de Passe

Argon2 incarne l'excellence cryptographique moderne. Winner de la Password Hashing Competition 2015, il offre une résistance inégalée aux attaques GPU/ASIC, une configuration flexible et une adoption massive. Le choix évident pour toute nouvelle application nécessitant une sécurité de pointe.

2015
PHC Winner
Memory-hard
GPU/ASIC résistant
2024
Standard moderne