PHPでは、 Hash_equalsは、2つの文字列が等しいかどうかを比較するために使用される関数です。ハッシュ値を検証するときなど、時間攻撃を防ぐためによく使用されます。 2つの文字列の各文字を比較して、比較プロセス時間が一定であることを確認することにより、セキュリティを改善します。
ただし、場合によっては、開発者は、 Hash_equalsを頻繁に使用すると、メモリ使用量とメモリリークの異常な成長につながる可能性があることがわかりました。この記事では、考えられる原因を分析し、メモリリークを避けるための提案を提供します。
hash_equals(string $ nowned_string、string $ user_string):bool
関数:2つの文字列が等しいかどうかを安全に比較します。
アプリケーションシナリオ:パスワードハッシュ比較、API署名検証など。
サンプルコード:
<?php
$known = '5f4dcc3b5aa765d61d8327deb882cf99';
$userInput = '5f4dcc3b5aa765d61d8327deb882cf99';
if (hash_equals($known, $userInput)) {
echo "正常に一致します";
} else {
echo "マッチが失敗しました";
}
?>
PHP自体はHash_equalsを比較的安定させますが、PHPのいくつかの拡張機能または特定のバージョンを使用すると、修復されていないメモリリークがある場合があります。
Hash_equalsでは、両方のパラメーターが文字列であり、同じ長さである必要があります。非弦または異なる長さのパラメーターを渡すと、特に問題を増幅するためのループ呼び出しで、基礎となるメモリの例外が発生する可能性があります。
Hash_equalsが非常に大きな文字列で繰り返し呼び出され、スクリプトで変数が適切にリリースされない場合、メモリの成長が発生する可能性があります。
呼び出し前に着信パラメーターをチェックして、それらが文字列であり、同じ長さであることを確認し、暗黙の変換によって引き起こされる潜在的な問題を回避します。
<?php
function safe_hash_equals($known, $user) {
if (!is_string($known) || !is_string($user)) {
return false;
}
if (strlen($known) !== strlen($user)) {
return false;
}
return hash_equals($known, $user);
}
?>
長期にわたるスクリプトまたはループでは、不必要な可変参照とクリーンメモリを時間内に避けてください。
<?php
for ($i = 0; $i < 100000; $i++) {
$known = 'hash_value_here';
$user = getUserInput(); // これが入力を取得する関数であると仮定します
safe_hash_equals($known, $user);
unset($user);
// また利用可能です gc_collect_cycles() 強制ガベージコレクション(注意して使用してください)
}
?>
多くのメモリ管理の問題は、PHPの新しいバージョンで修正されており、最新の安定したバージョンを使用することをお勧めします。また、関連する拡張機能の更新ステータスを確認してください。
可能であれば、結果をキャッシュするか、 hash_equalsへの繰り返しの呼び出しを避けて、メモリ圧力を低下させます。
Hash_equalsは、PHPの文字列を安全に比較するための優れたヘルパーですが、不適切な使用はメモリリークにつながる可能性があります。メモリリークを避けるための鍵は次のとおりです。
パラメーターが合法であり、タイプと長さが一致していることを確認してください。
変数を合理的に管理し、メモリをタイムリーにリリースします。
PHPおよび関連する拡張機能の最新バージョンを使用します。
不必要な複製コールを削減します。
これにより、システムのパフォーマンスに対するメモリリークの影響を回避しながら、アプリケーションのセキュリティを可能な限り最大限に保証できます。
PHPセキュリティ機能の使用について詳しく知りたい場合は、詳細については、 https://gitbox.net/php-manual/function.hash_equals.htmlなどの公式ドキュメントとコミュニティのベストプラクティスを参照してください。