17

私はcrypt()PHPでパスワードをハッシュするために使用しており、パスワードチェックを実行するときに結果のハッシュの同等性をテストする最も安全な方法を見つけようとしています。

私が見ることができる3つのオプションがあります:

オプション1-ダブルイコール

function checkPassword($hash, $password)
{
    return crypt($password, $hash) == $hash;
}

オプション2-トリプルイコール

function checkPassword($hash, $password)
{
    return crypt($password, $hash) === $hash;
}

オプション3-strcmp()

function checkPassword($hash, $password)
{
    return strcmp(crypt($password, $hash), $hash) === 0;
}

私の直感によると、タイプチェックがないため、オプション1は悪い考えであり、オプション2または3の方が優れている可能性があります。ただし、失敗する、または失敗する特定のケースがある===かどうかstrcmpはわかりません。この目的のために最も安全なのはどれですか?

4

4 に答える 4

21

===セキュリティに関しては、演算子を使用することを好みます。===PHPのような緩い型の言語のおかげで開発中に役立つ可能性があるため、比較を「支援」して一致を成功させるためにキャストに対応しようとせずに、2つのオペランドが完全に同じであることを保証します。

もちろん、オペランドの1つは信頼されるべきです。データベースからのハッシュは信頼できますが、ユーザー入力は信頼できません。

いつでもしばらくの間ディザリングを行うことができ==、特定のケースで使用するリスクはないと結論付けられます。多分。しかし、例えば

  "0afd9f7b678fdefca" == 0 is true
  "aafd9f7b678fdefca" == 0 is also true

PHPは「ハッシュ」を(おそらくatoiを使用して)0を与える数値に変換しようとするため、0がcrypt返される可能性は低いですが、パスワードが一致しない場合を最大化する(そしてサポートコールに応答する)ことをお勧めします。を使用して===、私が使用して考えていなかったまれなケースを許可するよりも==

についてstrcmpは、関数は<0orを返し>0、異なる場合は0を返し、等しい場合は0を返します。だが

  strcmp("3", 0003) returns 0
  strcmp("0003", 0003) returns -3

結局のところ、これは驚くべきことではありません。リテラル0003は実際には整数で3あり、strcmpは文字列を想定しているため、3はに変換され"3"ます。しかし、これは、 strcmpが関数で===あり、言語の一部であるため、この場合に発生する可能性のある変換があることを示しています。

したがって、その場合の私の好みは(とにかく===より速い)に行きます。==

于 2013-02-05T16:59:03.977 に答える
6

PHPに組み込まれているhash_equals()関数を使用する必要があります。独自の機能を作成する必要はありません。hash_equals()はブール値を返します。

私の意見では、ハッシュされた文字列はもちろん、文字列の比較に==または===を使用することは通常は良い考えではありません。

于 2014-11-21T16:59:07.080 に答える
0

それは正しくありません。関数の定義を見てください。PHPによると:

Returns < 0 if str1 is less than str2;

> 0 if str1 is greater than str2,

and 0 if they are equal

str1がstr2より小さい場合、0未満を返します。「未満」という句に注意してください。-1だけではなく、負の値が返されます。str1がstr2より大きい場合も同じことが起こりますが、ゼロ以外の正の値を返します。1の正の値、またはそれ以降の任意の数を返します。

strcmp()類似していることが判明した最後の文字で始まる2つの文字列の差である数値を返します。

次に例を示します。

$output = strcmp("red", "blue");

変数$outputには、16の値が含まれています

于 2013-09-13T16:26:30.900 に答える
-4

==あなたの場合は使うだけで十分だと思います。

==タイプに関係なく等しいかどうかをチェックし===ますが、タイプだけでなく等しいかどうかもチェックします。

1 == "1"= True

1 === "1"= False

タイプにはあまり関心がないので、シンプルにして、を使用し==ます。

于 2013-02-05T15:58:50.447 に答える