@peccul is peccu

(love peccu '(emacs lisp cat outdoor bicycle mac linux coffee))

PHPのmd5でハッシュ化して==で比較すると一致する2つの文字列

<?php
$first = md5("Password147186970!");
$second = md5("240610708");
if($first == $second){
  echo "same!";
}else{
  echo "wrong...";
}

この出力はsame!となります。

下記に実行例があります。

PHP code - 8 lines - codepad

比較が===ではなく==であるから、ということがわかったとして、なぜ同じになるのか。 上記2つの文字列のmd5ハッシュ値が0eで始まり、以降数字が並ぶからです。

PHPの==はご親切にも数値を表現する文字列を数値として扱います。 例えば文字列の"134"が数値の134として評価されます。 詳しくはこちら。

PHP: 文字列 - Manual

Man page of STRTOD

0eのあとに数字が続くと0の累乗とみなされるので数値の0として扱われます。 これより、md5ハッシュ値正規表現0e\d+にマッチすると比較時に両方とも0になっていたのです。

解決策は、比較時に==ではなく===を使うことです。

下記ネタ元には、同様にハッシュ値0e\d+となる入力値の一部が載っています。

Magic Hashes | WhiteHat Security Blog