2011-03-06 9 views
6

は、私が使うべきではif(strcmp(md5($string),$hash)==0)またはif(md5($string)==$hash)ハッシュされた文字列を比較する最良の方法は何ですか? (PHP)

+0

カスタムソート関数で 'strcmp'を使用します。 「通常の」使用の場合、文字列を直接比較する方が簡単で読みやすくなります。 –

+6

このスレッドを読んでいる人は、[それはしないでください** ** at all at **](http://phpsadness.com/sad/47)。 – ereOn

+1

単にハッシュを確実に比較したいのであれば、 '==='を使うだけです。セキュリティと潜在的なタイミング攻撃(ネットワークジッタにもかかわらず)に本当に関心があるなら、[this](https://github.com/delight-im/Faceless/issues/4)または[this] (https://github.com/delight-im/Faceless/pull/5)議論をするか、 'hash_equals()'関数(PHP 5.6+)を使用してください。 – caw

答えて

0

==は、非常に信頼性がないと、ここで他のユーザーによって示されています。代わりにstrcmp()を使用してください。あなたが本当に比較演算子を使用したい場合は

第三の選択肢は、あらゆる種類の型変換を実行しません===を使用することですので、種類と比較の目的のために値を保持します。

+0

どちらが優れたパフォーマンスを備えていますか? – webnat0

+0

==、以下の投稿のように1つのcomparsionしかないので、 –

+3

@ Da9:...と関数呼び出しはありません。 –

-4

私はif(md5($string) == $hash)が2(stcmp & ==)の代わりに1つの比較しかないので、より良いと思います。

md5は、バイナリセーフコンパイルを必要としないascii-charsのみを生成します。

+0

@MM答えを見てください。 2番目のすべてのmd5は廃止されました(ハッキングされる可能性があることが証明されています)。 shaを使用してください。 – Symba

+0

もちろん、あなたはmd5上でshaを使うべきです。しかし、質問者は、彼がどちらを使うべきか尋ねました。誰かがあなたに「あなたはイチゴのアイスクリームかチョコレートのアイスクリームが好きですか?」と尋ねると、「私はバニラアイスクリームをとる」と答えることはできません。さらに、問題はハッシュアルゴリズムを使用することではなく、値を比較することです。 –

+0

ここではアイスクリームについては言及しませんが、セキュリティについては言及しません。だから答えは確かに "あなたがここに提案したものは何も使わないでください!"です。 そして、BTW:SHA-1 **をパスワードとして使用してはいけません。 – rugk

15

文字列を比較する場合は、strcmpまたは===を使用してください。人々は===を好むので、strcmpは混乱する可能性があります(成功した場合は0を返します)。

===ではなく、==を使用する必要があります。 ==は、両方のオペランドをそのように解釈できる場合には整数に変換し、MD5ハッシュは整数に収まらないため、半分の周りで切り捨てられます。したがって、ハッシュの最初の半分だけが等しくなければなりません。 http://phpsadness.com/sad/47を参照してください。

パスワードをハッシュする場合は、MD5ではなくPBKDF2などの低速で強力なハッシュアルゴリズムを使用することを検討してください。

+4

うわー...本当に本当に悲しいです。 – BoltClock

20

タイミング攻撃にウィンドウを開く可能性があるので、認証などのハッシュを直接比較するときは、非常に注意が必要です

非常に直感的ではありませんが、文字列を完全に比較して最適化を避ける必要があります(つまり、文字が異なる場合は早めに終了する必要があります)。ここで

は、問題に関するいくつかのリンクです:

そして、ここではそれを修正するためにいくつかのアイデアです:

2

あなたがPHP 5.6より新しいものを使用して(を含む)している場合は、timing attack safe string comparison機能を使用する必要があります。

if (hash_equals($expected, $correct)) { 

} 

(あなたがPHP 5.5またはそれ以前、see here for equivalentsにしている場合。)

+0

本当に唯一正しい答えです。 –

0

実際にあなたがこのためにpassword_verifyを使用すると、他のすべてのpassword_*の機能を使用する必要があります。 PHP> = 5.5.0で利用可能です。

フォールバックとしてthis polyfillを使用できます。現在、PHP> = 5.3.7で動作します。

本当にこれを使用できない場合は、まだhash_equals(およびそのポリフィルは@MM)です。すでに言った。

関連する問題