現在の位置: ホーム> 最新記事一覧> パスワードの比較とそのソリューションにおけるHASH_Equals関数の一般的なエラーは何ですか?

パスワードの比較とそのソリューションにおけるHASH_Equals関数の一般的なエラーは何ですか?

gitbox 2025-06-27

PHPでは、 Hash_equals関数は、2つのハッシュ文字列が等しいかどうかを安全に比較するために使用される関数です。元の設計は、タイム攻撃を避けるためです。つまり、ハッカーはプログラムの応答時間にわずかな違いを使用して、パスワードが正しいかどうかを推測します。ただし、実際に使用すると、開発者は多くの場合、いくつかの一般的な間違いを犯し、 Hash_equals関数が予想されるセキュリティ効果を達成できなくなります。この記事では、これらのエラーについて詳しく説明し、ソリューションを提供します。

1。誤解:通常の文字列との混乱したハッシュ_equals

Hash_equalsの目的は、文字列と比較して時差を介してパスワード情報の漏れを防ぐことです。従来の==または===オペレーターとは異なり、 HASH_EQUALSは比較中の文字列の長さまたはコンテンツに依存しないため、時間攻撃を回避できます。

一般的な間違いの1つは、通常の文字列比較操作とHash_equalsを混乱させることです。例えば:

 <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>

ここでは、ハッシュ値を比較していますが、PHPは通常の比較操作に== OR ==を使用します。これにより、ハッシュ値の内容または長さに基づいて異なる最適化が行われ、時間が漏れます。

解決:
ハッシュ比較には常にhash_equalsを使用します。

 <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>

2。エラー理解: Hash_equalsを使用して、元のパスワードテキストとハッシュ値を誤って比較します

もう1つの一般的な間違いは、元のパスワードを保存されたハッシュ値と比較するときにHash_equalsを使用することです。これは、開発者がパスワードのプレーンテキストとハッシュ値を直接比較できると考えるかもしれない一般的な誤解です。

 <span><span><span class="hljs-comment">// エラーデモンストレーション</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>

Password_hashがハッシュ値を返すため、このコードは間違っています。Hash_equals2つのハッシュ文字列を比較するためにのみ使用でき、PlantextとHashを直接比較することはできません。

解決:
パスワードのクリアテキストとハッシュ値は、適切な関数( Password_verifyなど)を使用して最初に検証する必要があります。 password_verifyは、この目的のために設計された関数です。

 <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>

3.誤った使用:ハッシュ値の長さの一貫性を考慮しない

比較を実行するとき、ハッシュ値自体の内容を比較することに加えて、2つのハッシュ値の長さが同じかどうかもチェックします。長さが一貫していない場合、 Hash_equalsはすぐにFalseを返し、不要な計算を継続しないようにします。したがって、開発者は場合によっては、着信ハッシュ値の長さが異なり、エラーを引き起こすことに気付かない場合があります。

たとえば、ハッシュ(切り捨てやフォーマットなど)で保存するときに処理を行うと、ハッシュの長さが変化し、比較が失敗する可能性があります。

解決:
ハッシュを保存および比較するときは、一貫した形式を使用して、不要な変更を回避してください。 password_hash関数は標準のハッシュ形式を返し、手動操作を避けるようにします。

4.不正使用:さまざまなタイプのハッシュアルゴリズムの比較

Hash_equalsは、同じタイプのハッシュ値を比較するためにのみ使用できます。パスワードをハッシュするときに別のアルゴリズムを使用する場合(たとえば、 MD5SHA256を使用する)、 HASH_Equalsの比較は、異なるハッシュアルゴリズム間の比較を処理できないために失敗します。

 <span><span><span class="hljs-comment">// エラーデモンストレーション:md5 そして sha256 ハッシュ比較</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>

解決:
パスワードストレージと比較は、同じハッシュアルゴリズムを使用して使用されます。 password_hash関数を使用してハッシュ値を生成する場合、適切なハッシュアルゴリズム(通常はbcryptまたはargon2)を使用する場合、 password_verifyを介して検証するだけです。

5.不正使用: Hash_equalsの返品値を確認しないでください

Hash_equalsは、2つのハッシュ値が等しいかどうかを示すブール値を返します。開発者が値の正しい処理を無視すると、論理的な判断が誤っている可能性があります。

 <span><span><span class="hljs-comment">// エラーデモンストレーション:処理された返品値はありません</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>

ここでのエラーは、 hash_equalsではなく、エラー条件下で適切なプロセス処理の欠如です。パスワード検証プロセスのセキュリティを確保するには、パスワードが正しいかどうかに関係なく、フィードバックが正しいことを確認する必要があります。

解決:
hash_equalsの返品値に基づいて適切な判断を下すようにしてください:

 <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">// より安全なエラー処理,ロギングなど</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>

6。概要

Hash_equalsは、時間攻撃を防ぐための非常に重要なPHP関数ですが、全能ではなく、誤った使用がプログラムのセキュリティの脆弱性につながる可能性があります。一般的なエラーには、ハッシュ比較の混乱、プレーンテキストのパスワードをハッシュ値と誤って比較し、異なるハッシュアルゴリズムを使用した一貫性のないハッシュの長さを誤って比較し、返品値を無視することが含まれます。これらのエラーを解決するための鍵は、 Hash_equalsの使用シナリオを理解し、適切なシナリオでPassword_verifyを使用してパスワードの正確性を確認することです。

正しい実装とベストプラクティスを通じて、パスワード検証プロセスのセキュリティを大幅に改善し、潜在的な攻撃リスクを回避できます。