In PHP ist die Funktion Hash_equals eine Funktion, mit der sicher verglichen wird, ob zwei Hash -Zeichenfolgen gleich sind. Das ursprüngliche Design besteht darin, Zeitangriffe zu vermeiden, dh Hacker verwenden geringfügige Unterschiede in der Programmantwortzeit, um zu schließen, ob das Passwort korrekt ist. Im tatsächlichen Gebrauch machen Entwickler jedoch häufig einige häufige Fehler, was dazu führt, dass die Funktion der Hash_equals -Funktion den erwarteten Sicherheitseffekt nicht erreicht. In diesem Artikel werden diese Fehler im Detail erläutert und liefert Lösungen.
Der Zweck von Hash_Equals besteht darin, die Lecks von Kennwortinformationen durch den Zeitunterschied im Vergleich zu Zeichenfolgen zu verhindern. Im Gegensatz zum traditionellen == oder === Operator hängt Hash_equals nicht von der Länge oder dem Inhalt der Zeichenfolge während des Vergleichs ab, sodass Zeitangriffe vermieden werden können.
Einer der häufigen Fehler ist das verwirrende Hash_equals mit regulären String -Vergleichsoperationen. Zum Beispiel:
<span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$password</span></span><span> == </span><span><span class="hljs-variable">$storedPasswordHash</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is correct!"</span></span><span>;
}
</span></span>
Obwohl es Hash -Werte verglichen, verwendet PHP == oder == für gewöhnliche Vergleichsvorgänge, die unterschiedliche Optimierungen auf der Grundlage des Inhalts oder der Länge des Hash -Werts führen können, was zu Zeitverlust führt.
Lösung:
Verwenden Sie immer Hash_equals für den Hash -Vergleich:
<span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">hash_equals</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$storedPasswordHash</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is correct!"</span></span><span>;
}
</span></span>
Ein weiterer häufiger Fehler besteht darin, Hash_equals beim Vergleich des ursprünglichen Passworts mit dem gespeicherten Hash -Wert zu verwenden. Dies ist ein weit verbreitetes Missverständnis, das Entwickler vielleicht glauben, dass sie das Klebentext des Passworts direkt mit Hash -Werten vergleichen können.
<span><span><span class="hljs-comment">// Fehlerdemonstration</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">hash_equals</span></span><span>(</span><span><span class="hljs-variable">$password</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_BCRYPT))) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is correct!"</span></span><span>;
}
</span></span>
Dieser Code ist falsch, da Passwort_Hash einen Hash -Wert zurückgibt und Hash_equals nur zum Vergleichen von zwei Hash -Zeichenfolgen verwendet werden kann und Klartext und Hash nicht direkt vergleichen kann.
Lösung:
Der Kennwortlöschtext und der Hash -Wert sollten zunächst mithilfe einer entsprechenden Funktion (z. B. password_verify ) überprüft werden. password_verify ist eine Funktion für diesen Zweck:
<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">$storedPasswordHash</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is correct!"</span></span><span>;
}
</span></span>
Bei der Durchführung des Vergleichs werden zusätzlich zum Vergleich des Inhalts des Hash -Wertes selbst prüft, ob die Längen der beiden Hash -Werte gleich sind. Wenn die Länge inkonsistent ist, gibt Hash_equals sofort false zurück, um nicht weiterhin unnötige Berechnungen durchzuführen. Daher erkennen Entwickler in einigen Fällen möglicherweise nicht, dass sich die eingehenden Hash -Werte in der Länge unterscheiden und Fehler verursachen.
Wenn Sie beispielsweise beim Speichern eine gewisse Verarbeitung auf dem Hash (z. B. Kürzung oder Formatierung) durchführen, kann sich die Länge des Hashs ändern, was den Vergleich zu Fehlern verursacht.
Lösung:
Stellen Sie sicher, dass Sie beim Speichern und Vergleich von Hashes ein konsistentes Format verwenden und unnötige Änderungen vermeiden. Die Funktion password_hash gibt ein Standard -Hash -Format zurück und versucht, einen manuellen Betrieb zu vermeiden.
Hash_Equals können nur verwendet werden, um Hash -Werte desselben Typs zu vergleichen. Wenn ein anderer Algorithmus verwendet wird, wenn das Kennwort Hashing (z. B. unter Verwendung von MD5 und SHA256 ) heidet, schlägt der Hash_equals -Vergleich fehl, da er Vergleiche zwischen verschiedenen Hash -Algorithmen nicht verarbeiten kann.
<span><span><span class="hljs-comment">// Fehlerdemonstration:md5 Und sha256 Hash -Vergleich</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">hash_equals</span></span><span>(</span><span><span class="hljs-title function_ invoke__">md5</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>), </span><span><span class="hljs-title function_ invoke__">sha256</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>))) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is correct!"</span></span><span>;
}
</span></span>
Lösung:
Der Speicherspeicher und -vergleich werden mit demselben Hashing -Algorithmus verwendet. Wenn Sie die Funktion password_hash verwenden, um Hash -Werte zu generieren, verwendet sie den entsprechenden Hashing -Algorithmus (normalerweise Bcrypt oder Argon2), Sie müssen diese nur über password_verify überprüfen.
Hash_equals gibt einen booleschen Wert zurück, der angibt, ob die beiden Hash -Werte gleich sind. Wenn der Entwickler die korrekte Handhabung des Wertes ignoriert, kann dies zu falschen logischen Urteilen führen.
<span><span><span class="hljs-comment">// Fehlerdemonstration:Kein Rückgabewert verarbeitet</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">hash_equals</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$storedPasswordHash</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is correct!"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is incorrect!"</span></span><span>;
}
</span></span>
Der Fehler hier ist nicht Hash_equals , sondern das Fehlen einer ordnungsgemäßen Prozessbehandlung unter Fehlerbedingungen. Um die Sicherheit des Kennwortüberprüfungsprozesses zu gewährleisten, muss sichergestellt werden, dass das Feedback korrekt ist, unabhängig davon, ob das Kennwort korrekt ist oder nicht.
Lösung:
Stellen Sie sicher, dass Sie auf der Grundlage des Rückgabewerts von Hash_Equals entsprechende Urteile fällen:
<span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">hash_equals</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$storedPasswordHash</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is correct!"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-comment">// Sicherere Fehlerbehandlung,Wie Protokollierung</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Invalid password!"</span></span><span>;
}
</span></span>
Hash_equals ist eine sehr wichtige PHP -Funktion, um Zeitangriffe zu verhindern, aber es ist nicht allmächtig, und eine falsche Verwendung kann zu Sicherheitslücken im Programm führen. Zu den häufigen Fehlern gehören verwirrende Hash -Vergleiche, fälschlicherweise Vergleich von Klartextkennwörtern mit Hash -Werten, inkonsistente Hash -Länge, die Verwendung verschiedener Hash -Algorithmen und das Ignorieren des Rückgabewerts. Der Schlüssel zur Lösung dieser Fehler liegt darin, die Nutzungsszenarien von Hash_equals zu verstehen und in den entsprechenden Szenarien Passwort_verify zu verwenden, um die Richtigkeit des Kennworts zu überprüfen.
Durch die korrekte Implementierung und Best Practices kann die Sicherheit im Kennwortüberprüfungsprozess erheblich verbessert und potenzielle Angriffsrisiken vermieden werden.