PHP Hashes und ihre Probleme

Ein schon ein etwas älteres Phänomen, welches mir demletzt erneut über den Weg gelaufen ist und ich es deswegen für „verbloggenswert“ halte:

if (md5('240610708') == md5('QNKCDZO'))
{
	echo "yep equal";
}

Ups? Eine MD5-Kollision? Nein. Eine Eigenart von PHP.

var_dump(md5('240610708')); //string(32) "0e462097431906509019562988736854"
var_dump(md5('QNKCDZO'));   //string(32) "0e830400451993494058024219903391"

2 verschiedene Strings, die aber laut PHP-Vergleich identisch sein sollen? Genau da liegt der Knackpunkt: Die Strings sind gleich, aber nicht identisch. Da beide mit 0e anfangen, werden sie als Exponentialdarstellung einer Zahl aufgefasst. Und da 0irgendwas immer 0 ergibt, sind die beiden Hashes im Vergleich auch gleich.

Das „Problem“ lässt sich einfach lösen, indem mit === verglichen wird. Dann evaluiert PHP den Zahlenwert des Strings nicht mehr. Oder indem strcmp verwendet wird:

var_dump(strcmp(md5('240610708'), md5('QNKCDZO'))); //int(-1)

SHA und Konsorten sind für diese Problematik genau so anfällig, es ist nur entsprechend unwahrscheinlicher, dass es zu solch einem „0e“-Phänomen kommt. In der Praxis hätten Angreifer also eine bessere Chance, wenn zu „0e“ evaluierende Hashes beim Bruteforcen vorrangig probiert werden. Aber auch dann ist der Angriff selbstverständlich von der Nachlässigkeit des Entwicklers abhängig: Sobald mit === verglichen wird (bzw. ein „ordentliches“ Hash-Verfahren wie bcrypt mit Salt verwendet wird) sieht es düsterer aus.

Weitere Posts:

Dieser Beitrag wurde unter php, Security, Quicktips, webdev veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Eine Antwort auf PHP Hashes und ihre Probleme

  1. Daniel Br. sagt:

    „demletzt“ – hach herrlich. :) Ist aber ein echt interessantes Thema. Viele Grüße nach Darmstadt!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.