Position actuelle: Accueil> Derniers articles> [Comment générer un sel sûr en PHP? La bonne façon que vous devez savoir

[Comment générer un sel sûr en PHP? La bonne façon que vous devez savoir

gitbox 2025-06-15

Lorsque vous utilisez HASH_PBKDF2 pour le cryptage de mot de passe, le sel est un composant clé pour assurer la sécurité. Bien que de nombreux développeurs savent que HASH_PBKDF2 est une fonction de dérivation de clé de mot de passe, ils ignorent comment générer et utiliser correctement et en toute sécurité le sel . Cet article expliquera en profondeur le rôle du sel , les malentendus communs et les pratiques recommandées pour générer des sels sûrs en PHP.

1. Pourquoi le sel est-il crucial?

Le rôle du sel est d'empêcher le risque d'attaques de table arc-en-ciel et le même mot de passe générant le même hachage. Sans sel , un attaquant n'a besoin que d'une table de hash de mot de passe pour inverser le mot de passe en texte clair. L'ajout de sel rend chaque cryptage unique, et même si deux utilisateurs définissent le même mot de passe, leurs valeurs de hachage sont complètement différentes.

2. Introduction à hash_pbkdf2

Le prototype de fonction HASH_PBKDF2 de PHP est le suivant:

 <span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-title function_ invoke__">hash_pbkdf2</span></span><span> (
    </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$algo</span></span><span>,
    </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$password</span></span><span>,
    </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$salt</span></span><span>,
    </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$iterations</span></span><span>,
    </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$length</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>,
    </span><span><span class="hljs-keyword">bool</span></span><span> </span><span><span class="hljs-variable">$binary</span></span><span> = </span><span><span class="hljs-literal">false</span></span><span>
)
</span></span>

Le paramètre $ sel est utilisé pour augmenter le caractère unique du hachage, de sorte que la façon dont elle est générée est cruciale.

3. Erreurs courantes

  1. Utilisez une chaîne fixe comme sel:

     <span><span><span class="hljs-variable">$salt</span></span><span> = </span><span><span class="hljs-string">'123456'</span></span><span>;
    </span></span>

    C'est un comportement très dangereux. Le sel fixe signifie que les valeurs de hachage pour tous les utilisateurs sont susceptibles d'être répétées.

  2. Générer en utilisant des fonctions simples:

    Par exemple, les fonctions telles que uniqid () et mt_rand () ne sont pas suffisamment aléatoires ou peuvent être prédites.

     <span><span><span class="hljs-variable">$salt</span></span><span> = </span><span><span class="hljs-title function_ invoke__">uniqid</span></span><span>();
    </span></span>

    Bien qu'apparemment unique, il manque d'entropie suffisante et n'est pas recommandé à des fins de sécurité.

4. La bonne façon de générer en toute sécurité le sel

Il est recommandé d'utiliser des fonctions au niveau de la sécurité du cryptage fourni par PHP pour générer du sel :

 <span><span><span class="hljs-variable">$salt</span></span><span> = </span><span><span class="hljs-title function_ invoke__">random_bytes</span></span><span>(</span><span><span class="hljs-number">16</span></span><span>); </span><span><span class="hljs-comment">// 16 octet = 128 Peu</span></span><span>
</span></span>

Si vous devez le stocker sous forme de chaîne (par exemple, enregistrez-le dans une base de données), vous pouvez utiliser Bin2Hex () ou Base64_encode () pour encoder:

 <span><span><span class="hljs-variable">$salt</span></span><span> = </span><span><span class="hljs-title function_ invoke__">bin2hex</span></span><span>(</span><span><span class="hljs-title function_ invoke__">random_bytes</span></span><span>(</span><span><span class="hljs-number">16</span></span><span>)); </span><span><span class="hljs-comment">// 32 Chaîne hexadécimale de caractères</span></span><span>
</span></span>

5. Exemple d'utilisation complet

Voici un exemple complet de la façon de crypter en toute sécurité les mots de passe à l'aide de hash_pbkdf2 :

 <span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">hashPassword</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-variable">$password</span></span></span><span>) {
    </span><span><span class="hljs-variable">$salt</span></span><span> = </span><span><span class="hljs-title function_ invoke__">bin2hex</span></span><span>(</span><span><span class="hljs-title function_ invoke__">random_bytes</span></span><span>(</span><span><span class="hljs-number">16</span></span><span>)); </span><span><span class="hljs-comment">// Générer en toute sécurité salt</span></span><span>
    </span><span><span class="hljs-variable">$iterations</span></span><span> = </span><span><span class="hljs-number">100000</span></span><span>;
    </span><span><span class="hljs-variable">$algo</span></span><span> = </span><span><span class="hljs-string">'sha256'</span></span><span>;
    </span><span><span class="hljs-variable">$length</span></span><span> = </span><span><span class="hljs-number">64</span></span><span>;

    </span><span><span class="hljs-variable">$hash</span></span><span> = </span><span><span class="hljs-title function_ invoke__">hash_pbkdf2</span></span><span>(</span><span><span class="hljs-variable">$algo</span></span><span>, </span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$salt</span></span><span>, </span><span><span class="hljs-variable">$iterations</span></span><span>, </span><span><span class="hljs-variable">$length</span></span><span>, </span><span><span class="hljs-literal">false</span></span><span>);

    </span><span><span class="hljs-keyword">return</span></span><span> [
        </span><span><span class="hljs-string">'salt'</span></span><span> =&gt; </span><span><span class="hljs-variable">$salt</span></span><span>,
        </span><span><span class="hljs-string">'hash'</span></span><span> =&gt; </span><span><span class="hljs-variable">$hash</span></span><span>,
        </span><span><span class="hljs-string">'algo'</span></span><span> =&gt; </span><span><span class="hljs-variable">$algo</span></span><span>,
        </span><span><span class="hljs-string">'iterations'</span></span><span> =&gt; </span><span><span class="hljs-variable">$iterations</span></span><span>
    ];
}

</span><span><span class="hljs-comment">// Exemple d&#39;utilisation</span></span><span>
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-title function_ invoke__">hashPassword</span></span><span>(</span><span><span class="hljs-string">'MySecretPassword'</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">print_r</span></span><span>(</span><span><span class="hljs-variable">$result</span></span><span>);
</span></span>

6. Comment vérifier le mot de passe?

Lors de la vérification du mot de passe, vous devez lire le sel d'origine, les itérations et l'algo de la base de données, puis régénérer le hachage de la même manière à la comparaison:

 <span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">verifyPassword</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-variable">$password</span></span></span><span>, </span><span><span class="hljs-variable">$storedHash</span></span><span>, </span><span><span class="hljs-variable">$salt</span></span><span>, </span><span><span class="hljs-variable">$iterations</span></span><span>, </span><span><span class="hljs-variable">$algo</span></span><span> = </span><span><span class="hljs-string">'sha256'</span></span><span>, </span><span><span class="hljs-variable">$length</span></span><span> = </span><span><span class="hljs-number">64</span></span><span>) {
    </span><span><span class="hljs-variable">$hash</span></span><span> = </span><span><span class="hljs-title function_ invoke__">hash_pbkdf2</span></span><span>(</span><span><span class="hljs-variable">$algo</span></span><span>, </span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$salt</span></span><span>, </span><span><span class="hljs-variable">$iterations</span></span><span>, </span><span><span class="hljs-variable">$length</span></span><span>, </span><span><span class="hljs-literal">false</span></span><span>);
    </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">hash_equals</span></span><span>(</span><span><span class="hljs-variable">$storedHash</span></span><span>, </span><span><span class="hljs-variable">$hash</span></span><span>);
}
</span></span>

Hash_Equals peut empêcher les attaques de synchronisation et est un choix sûr lors de la comparaison des hachages.

7. Conclusion

Pour utiliser HASH_PBKDF2 en toute sécurité, la clé consiste à générer un sel aléatoire fort et à définir un nombre suffisant d'itérations. N'utilisez pas les sels d'entropie statiques ou bas, sinon il détruira la sécurité de l'ensemble du processus de cryptage. Dans le domaine de la sécurité des mots de passe, il n'y a pas de soi-disant «utilisation» et chaque détail mérite d'être pris au sérieux. J'espère que cet article peut vous aider à comprendre la bonne génération de sel dans HASH_PBKDF2 , afin de créer une application PHP plus sécurisée.