Cet article est destiné aux développeurs qui souhaitent comprendre et appliquer correctement les fonctions de hachage dans PHP. Nous comparerons MD5 et SHA-1 pour donner des suggestions claires et pragmatiques des principes, une sortie, une résistance aux collisions, une vitesse, des utilisations typiques et une utilisation pratique en PHP, et expliquer des alternatives plus sûres et des précautions d'utilisation.
Fonction de hachage (hachage) : accepte l'entrée de toute longueur et produit un "résumé" de longueur fixe. Il est souvent utilisé pour vérifier l'intégrité des données, générer une base de signature, faire des index, etc.
Irrrévabilité : les fonctions de hachage doivent être unidirectionnelles - théoriquement, l'entrée d'origine ne peut pas être déduite du résumé (mais pas absolue, selon la capacité de l'attaquant).
Collision : un cas où différentes entrées produisent la même sortie. Le hachage idéal devrait être difficile à trouver des collisions.
Longueur de sortie
MD5: 128 bits, généralement exprimés en hexadécimal à 32 caractères (tels que d41d8cd98f00b204e9800998ecf8427e ).
SHA-1: 160 bits, généralement exprimés en 40 caractères hexadécimaux (comme DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 ).
Sécurité (Résumé)
MD5: Il s'est avéré avoir des attaques de collision pratiques et réalisables et ne peut pas être utilisé dans des scénarios sensibles à la sécurité (signatures, certificats, stockage de mot de passe, etc.).
SHA-1: plus fort que MD5, mais a également été fissuré empiriquement (recherche / preuves expérimentales pour trouver des collisions) et a été progressivement déprécié comme un hachage sûr.
vitesse
MD5 est généralement plus rapide que SHA-1 (état interne plus court et moins de volume de calcul), mais la différence de vitesse n'est pas la principale considération dans le matériel moderne - la sécurité est plus importante.
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-string">"hello world"</span></span><span>;
</span><span><span class="hljs-comment">// MD5</span></span><span>
</span><span><span class="hljs-variable">$md5</span></span><span> = </span><span><span class="hljs-title function_ invoke__">md5</span></span><span>(</span><span><span class="hljs-variable">$data</span></span><span>); </span><span><span class="hljs-comment">// 32 hex</span></span><span>
</span><span><span class="hljs-variable">$md5_raw</span></span><span> = </span><span><span class="hljs-title function_ invoke__">md5</span></span><span>(</span><span><span class="hljs-variable">$data</span></span><span>, </span><span><span class="hljs-literal">true</span></span><span>); </span><span><span class="hljs-comment">// Binaire d'origine 16 octet</span></span><span>
</span><span><span class="hljs-comment">// SHA-1</span></span><span>
</span><span><span class="hljs-variable">$sha1</span></span><span> = </span><span><span class="hljs-title function_ invoke__">sha1</span></span><span>(</span><span><span class="hljs-variable">$data</span></span><span>); </span><span><span class="hljs-comment">// 40 hex</span></span><span>
</span><span><span class="hljs-variable">$sha1_raw</span></span><span> = </span><span><span class="hljs-title function_ invoke__">sha1</span></span><span>(</span><span><span class="hljs-variable">$data</span></span><span>, </span><span><span class="hljs-literal">true</span></span><span>); </span><span><span class="hljs-comment">// Binaire d'origine 20 octet</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"MD5: <span class="hljs-subst">$md5</span></span></span><span>\n";
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"SHA1: <span class="hljs-subst">$sha1</span></span></span><span>\n";
</span></span>Pour l'authentification des messages (vérification d'intégrité plus sécurisée) qui nécessite des clés, utilisez HMAC:
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$key</span></span><span> = </span><span><span class="hljs-string">"secret-key"</span></span><span>;
</span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-string">"important payload"</span></span><span>;
</span><span><span class="hljs-comment">// Recommandé d'utiliser un hachage plus long et plus sûr(Exemple:sha256)</span></span><span>
</span><span><span class="hljs-variable">$hmac</span></span><span> = </span><span><span class="hljs-title function_ invoke__">hash_hmac</span></span><span>(</span><span><span class="hljs-string">'sha256'</span></span><span>, </span><span><span class="hljs-variable">$data</span></span><span>, </span><span><span class="hljs-variable">$key</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"HMAC-SHA256: <span class="hljs-subst">$hmac</span></span></span><span>\n";
</span></span>Seule l'identification unique et la vérification rapide unique (les petits risques sont acceptables)
MD5 ou SHA-1 peuvent être utilisés pour générer du hachage de nom de fichier, des clés de cache simples et un jugement rapide de déduplication (mais ne peuvent pas être invoqués comme une forte garantie de cohérence).
Utilisé pour des scénarios sûrs et sensibles (absolument pas recommandés)
Stockage de mot de passe, signature numérique, empreinte digitale TLS / Certificat, vérification de signature, etc.: N'utilisez pas MD5 / SHA-1 . Les deux ont des attaques de collision pratiques (en particulier MD5), et l'attaquant peut forger différents messages du même digest.
Vérification de l'intégrité du fichier
S'il s'agit uniquement d'éviter la corruption accidentelle pendant la transmission (scénario non conflictuel), MD5 / SHA-1 est toujours courant dans la page de téléchargement du fichier. Mais si vous vous inquiétez de la falsification malveillante, veuillez utiliser un hachage plus fort (SHA-256/512) ou une signature (HMAC / Public et Private Key Signature).
MD5 : Il y a eu plusieurs attaques de collision et attaques pratiques depuis le début des années 2000 et ont été largement obsolètes à des fins de sécurité.
SHA-1 : longtemps considéré comme plus sûr que MD5, mais la recherche et les expériences ont montré des collisions pratiques (telles que la démonstration pratique des collisions publiées par le monde universitaire en 2017), il devrait donc également être évité dans les situations où les exigences de sécurité sont élevées.
(Remarque: Ce qui précède est un aperçu. La pratique de recherche et d'ingénierie publiée montre que les deux sont insuffisants pour résister aux collisions.)
Les mots de passe utilisent toujours des fonctions de hachage de mot de passe spécial : l'utilisation de mot de passe_hash () / mot de passe_verify () , PHP par défaut ( mot de passe_default ) utilise des algorithmes de sécurité modernes (tels que BCrypt ou une meilleure implémentation) et gère automatiquement les sels aléatoires et les facteurs de coût.
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// Hachage et vérification du mot de passe(Exemple)</span></span><span>
</span><span><span class="hljs-variable">$password</span></span><span> = </span><span><span class="hljs-string">'user-password'</span></span><span>;
</span><span><span class="hljs-variable">$hash</span></span><span> = </span><span><span class="hljs-title function_ invoke__">password_hash</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, PASSWORD_DEFAULT);
</span><span><span class="hljs-comment">// stockage $hash Aller à la base de données</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">password_verify</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$hash</span></span><span>)) {
</span><span><span class="hljs-comment">// Vérification a été adoptée</span></span><span>
}
</span></span>L'intégrité des messages et l'authentification sont utilisées avec HMAC ou Signature : pour l'environnement contradictoire, veuillez utiliser hash_hmac () (par exemple, SHA256 ou SHA512 ), ou utilisez une signature de clé publique (OpenSSL_SIGN, etc.):
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$tag</span></span><span> = </span><span><span class="hljs-title function_ invoke__">hash_hmac</span></span><span>(</span><span><span class="hljs-string">'sha256'</span></span><span>, </span><span><span class="hljs-variable">$message</span></span><span>, </span><span><span class="hljs-variable">$secret_key</span></span><span>);
</span></span>Généralement, les séries SHA-2 ou SHA-3 sont préférées pour le hachage : par exemple, SHA256 , SHA512 , qui peut être utilisé dans PHP via Hash ('Sha256', Data) ou Hash ('Sha512', $ data) ; Ceux-ci sont nettement meilleurs que MD5 / SHA-1 en force.
Si vous devez traiter le binaire plus efficacement, vous pouvez utiliser la sortie binaire d'origine ( MD5 ($ data, true) / sha1 ($ data, true) ) et la base64 codage ou transmission des résultats.
N'essayez pas de créer votre propre schéma de hachage de mot de passe "en utilisant des hachats SALT + multiples" : les erreurs sont sujettes à la maintenance. Veuillez utiliser l'API de hachage de mot de passe recommandé par la langue / le cadre.
Longueur de sortie: md5 = 128 bits (32 hex), sha-1 = 160 bits (40 hex).
Sécurité: SHA-1> MD5, mais ni l'un ni l'autre ne convient plus aux scénarios critiques de sécurité.
Vitesse: MD5 est légèrement plus rapide, mais la différence ne devrait pas être les critères de sélection (priorité de sécurité).
Objectif recommandé: uniquement pour des scénarios d'identification ou compatibles uniques non sécurisés; Veuillez utiliser SHA-2 / SHA-3 / HMAC / PASSOTS_HASH à des fins sûres.
Si vous écrivez un nouveau code et que vous vous souciez de la sécurité, n'utilisez pas MD5 ou SHA-1 - utilisez Hash ('Sha256', $ data) / hash_hmac ('sha256', $ data, $ key) pour l'intégrité et l'authentification, et utilisez un mot de passe_hash () pour gérer les mots de passe; Ne considérez que MD5 / SHA-1 dans des scénarios compatibles avec les systèmes historiques ou qui ne sont pas liés à la sécurité.