Password hash PHP : Sécurisez vos mots de passe efficacement

Dans le monde du développement web, la sécurité des mots de passe représente un enjeu majeur. Stocker ces informations sensibles sans les crypter ou sans un chiffrement inadéquate expose vos utilisateurs à des risques importants, comme les attaques par dictionnaire ou les fuites de données.Les certificats SSL ne sont pas suffisants pour sécuriser le code-source de votre application web que vous utilisiez un framework ou un cms comme wordpress Heureusement, PHP propose une solution moderne et robuste avec la fonction password_hash(), qui simplifie grandement l’implémentation de bonnes pratiques cryptographiques.Il existe aussi son pendant pour vérifier que le mot de passe utilisateur corresponde au hash

Signature de la fonction password hash PHP

La fonction password_hash() constitue le cœur de l’API de gestion des mots de passe en PHP. Sa signature complète s’écrit comme suit : 

password_hash(string $motdepasse, string|int|null $algorithme, array $options = [])

Ce prototype révèle trois paramètres essentiels qui permettent une grande flexibilité tout en garantissant une sécurité optimale.

  •  $motdepasse, correspond simplement à la chaîne de caractères fournie par l’utilisateur lors de son inscription ou de sa connexion. Il s’agit du mot de passe en clair que vous devez transformer en une version protégée.
  • $algorithme, définit le type de hachage à appliquer via des constantes prédéfinies comme PASSWORD_DEFAULT ou PASSWORD_BCRYPT.
  •  $options accepte un tableau associatif pour affiner le comportement, comme le niveau de complexité du calcul.

Voici un exemple concret d’utilisation basique qui illustre parfaitement cette signature dans un contexte d’inscription utilisateur. Vous venez de remplir un formulaire sur votre navigateur et envoyez les données au serveur web. Avant de stocker votre mot de passe en base de données, il va passer dans un tunnel de cryptage afin que son déchiffrement devienne impossible.

<?php
// Mot de passe saisi par l'utilisateur
$motdepasse = 'MonMotDePasseSecure123!';

// Génération du hash avec l'algorithme par défaut
$hash = password_hash($motdepasse, PASSWORD_DEFAULT);

echo $hash; 
// Exemple de sortie : $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi
?>

Cette ligne de code génère une chaîne unique de 60 caractères environ, qui intègre à la fois l’algorithme de hashage utilisé, un sel automatique et le hachage final. Vous pouvez stocker cette données chiffrées directement en base de données sans aucune manipulation supplémentaire, ce qui rend l’approche particulièrement pratique pour les développeurs.

Les options salt et cost

Pour renforcer encore la protection, la fonction password_hash() propose deux options clés : salt et cost. Comprendre leur rôle et leurs implications permet d’adapter la sécurité à vos besoins spécifiques tout en évitant les pièges courants.

L’option cost agit comme un facteur de travail qui détermine le temps de calcul nécessaire au hachage. Exprimé sous forme d’entier (généralement entre 10 et 13 par défaut), il multiplie exponentiellement la charge processeur. Plus cette valeur augmente, plus il devient difficile pour un attaquant d’effectuer des essais massifs par force brute.

Observez cet exemple où nous réglons explicitement le cost à 12 pour un équilibre performant :

<?php
$motdepasse = 'MonMotDePasseSecure123!';
$options = [
    'cost' => 13  // Temps de calcul environ 0,3 seconde sur un serveur standard
];

$hash = password_hash($motdepasse, PASSWORD_BCRYPT, $options);
echo $hash;
?>

Testez cette valeur sur votre environnement : si le hachage prend moins de 0,1 seconde, augmentez-la progressivement pour contrer l’évolution des capacités matérielles des attaquants.

Quant au salt, il s’agit d’une chaîne aléatoire prépendue au mot de passe avant hachage, conçue pour neutraliser les attaques par tables rainbow (pré-calculs de hachages). Bien que tentant de le générer manuellement, il est fortement déconseillé de fournir votre propre sel à password_hash(). PHP gère cela automatiquement avec une génération cryptographiquement sûre via random_bytes(), évitant ainsi les erreurs humaines comme la réutilisation de sels ou des longueurs inadaptées.

Le sel généré s’intègre directement dans la chaîne de hachage finale, visible au début (par exemple, après $2y$10$). Cette approche automatique libère le développeur de toute gestion manuelle et garantit une unicité parfaite pour chaque mot de passe, même identiques. En résumé, omettez toujours l’option salt pour profiter de cette sécurité intégrée et infaillible.

Les différents algorithmes de hashage disponibles

PHP supporte plusieurs algorithmes via password_hash(), chacun adapté à des scénarios précis. Le choix dépend de votre version de PHP et des ressources serveur disponibles. Explorons les principaux avec des exemples pratiques.

PASSWORD_DEFAULT : Le choix recommandé

Cette constante pointe vers l’algorithme jugé le plus sûr par les mainteneurs de PHP à un instant donné. Actuellement, elle utilise bcrypt, mais pourrait migrer vers Argon2 dans les futures versions. C’est l’option idéale pour la plupart des projets, car elle évolue automatiquement avec PHP.

<?php
$motdepasse = 'MonMotDePasseSecure123!';
$hash = password_hash($motdepasse, PASSWORD_DEFAULT, ['cost' => 13]);

// Vérification lors de la connexion
if (password_verify($motdepasse, $hash)) {
    echo "Authentification réussie !";
} else {
    echo "Mot de passe incorrect.";
}
?>

Cette polyvalence assure une protection future-proof sans modification de code.

PASSWORD_BCRYPT : Le classiqueet robuste

Basé sur l’algorithme Blowfish, bcrypt reste extrêmement populaire pour sa maturité et sa compatibilité universelle. Il limite la longueur des mots de passe à 72 caractères et produit des hachages de 60 octets commençant par $2y$$2x$ ou $2a$.

<?php
$options = [
    'cost' => 14  // Plus élevé pour une sécurité renforcée
];
$hash = password_hash('MonMotDePasseSecure123!', PASSWORD_BCRYPT, $options);

echo "Hash bcrypt : " . $hash;
// Sortie typique : $2y$14$exempleDeSaltEtHashLong
?>

Bcrypt excelle dans les environnements contraints en mémoire, tout en résistant admirablement aux attaques GPU.

PASSWORD_ARGON2I et PASSWORD_ARGON2ID : Les modernes gourmands en calcul

Argon2, lauréat du concours international de hachage de mots de passe, se distingue par sa résistance aux attaques par canaux secondaires. PASSWORD_ARGON2I protège contre les attaques temporelles, tandis que PASSWORD_ARGON2ID hybride offre un équilibre optimal (nécessite PHP 7.3+ avec libsodium).

<?php
$options = [
    'memory_cost' => 65536,  // 64 MiO de RAM
    'time_cost'   => 4,      // 4 itérations
    'threads'     => 2       // Parallélisme
];
$hash = password_hash('MonMotDePasseSecure123!', PASSWORD_ARGON2ID, $options);

if (password_verify('MonMotDePasseSecure123!', $hash)) {
    echo "Argon2ID valide !";
}
?>

Ces options consomment plus de mémoire, rendant les attaques parallèles sur ASIC coûteuses. Vérifiez le support via password_algos() avant implémentation.

Password needs rehash : mettre à jour son le hash de son mot de passe

Toute implémentation se complète par password_verify() pour valider les connexions, et password_needs_rehash() pour mettre à jour les anciens hachages sans intervention utilisateur :

<?php
$ancienHash = $hashDeLaBase;
$nouvellesOptions = ['cost' => 14];

if (password_verify($motdepasse, $ancienHash)) {
    if (password_needs_rehash($ancienHash, PASSWORD_DEFAULT, $nouvellesOptions)) {
        $nouveauHash = password_hash($motdepasse, PASSWORD_DEFAULT, $nouvellesOptions);
        // UPDATE users SET password = ? WHERE id = ?
    }
    // Session OK
}
?>

Cette stratégie permet une évolution transparente vers des standards plus élevés.

Ces algorithmes de hashage sont ils symétriques ?

Non, les algorithmes utilisés par password_hash() (bcrypt, Argon2i, Argon2id) ne sont ni symétriques ni asymétriques. Ce sont des fonctions de hachage à sens unique (one-way hash functions), une catégorie cryptographique distincte.

Pourquoi « pas symétrique » ?

Le hachage via l’algorithme de chiffrement bcrypt/Argon2 détruit l’information intentionnellement  pour rendre la restauration sécurisée, même avec la « clé ». Vous ne restaurer jamais le mot de passe, vous le comparez uniquement :

<?php
// ✅ SEULE opération possible
if (password_verify('MonPass123', $hash)) {
    echo "Mot de passe correct";
}
?>

Origine de la confusion

Bcrypt repose sur Blowfish (symétrique), mais l’Eksblowfish le transforme en hachage adaptatif :

  • Salt unique par mot de passe
  • Cost qui ralentit les calculs
  • Fonction de dérivation (PBKDF) au lieu de chiffrement simple

Argon2 suit le même principe : gourmand en mémoire/temps, mais toujours irréversible.

Peut on utilisé md5 et sha?

MD5 et SHA sont aussi des fonctions de hachage à sens unique (comme bcrypt/Argon2), mais obsolètes et dangereuses pour sécuriser les mots de passe.

Pourquoi les éviter absolument ?

AlgorithmeTaille hashStatut sécurité VitesseUsage actuel
MD5128 bits (32 hex)COMPROMIS – collisions en 2h⚡ Très rapide❌ Mots de passe, ✅ Checksum fichiers
SHA-1160 bits (40 hex)COMPROMIS – collisions possibles⚡ Rapide❌ Tout usage sécurité
SHA-256256 bitsSÛR mais rapide⚡ Rapide✅ Signatures, ❌ Mots de passe seuls
bcrypt184 bitsSÛR + lent🐌 Lent (cost)✅ Mots de passe

Démo du problème

<?php
// ❌ DANGEREUX - 0,0001 seconde par hash
$motdepasse = 'password123';
$md5 = md5($motdepasse);     // 5f4dcc3b5aa765d61d8327deb882cf99
$sha1 = sha1($motdepasse);   // 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8

// Un attaquant teste 1 milliard mots/seconde avec MD5/SHA1
// Avec bcrypt : 1000 mots/seconde maximum
?>

Pourquoi si dangereux ?

  1. Trop rapides : 10⁹ hashes/seconde sur GPU vs 10³ pour bcrypt
  2. Collisions prouvées : MD5 depuis 2004, SHA-1 depuis 2017
  3. Rainbow tables : milliards de mots de passe pré-hachés disponibles
  4. Salt manuel inefficace : les attaquants salent aussi !

En adoptant password_hash(), vous protégez durablement vos applications contre les menaces actuelles et futures. Implémentez dès aujourd’hui pour une sécurité sans compromis !

Sources: php.net

Cours

Variables et types

Manipulation de chaînes

Tableaux

Fichiers et système

Sécurité, session et cookie