PHPでは、パスワードのハッシュには陰窩機能がよく使用されます。これにより、ハッシュのセキュリティを塩値(塩)によって強化して、レインボーテーブル攻撃などのセキュリティリスクを防ぎます。ただし、多くの開発者は、地下室を使用するときにハードコードの塩値に慣れているため、セキュリティリスクにつながる可能性があります。この記事では、ハードコーディングされた塩値を回避する方法を詳細に説明し、パスワードストレージのセキュリティを改善します。
ハードコーディングされた塩値は、次のようなコードに直接固定塩の弦を書くことを指します。
$salt = '$6$rounds=5000$fixedsaltstring$';
$hash = crypt($password, $salt);
そうすることには明らかなリスクがあります:
塩の値の再利用:すべてのユーザーのパスワードハッシュは同じ塩を使用し、攻撃者は攻撃を事前に計算することで攻撃を事前計算できます。
露出した塩値:ソースコードが漏れていて、攻撃者が塩について知っている場合、ハッシュ亀裂の難しさは大幅に減少します。
拡張が難しい:塩戦略を変更する必要がある場合、ハードコーディングされた部分を変更することは非常に柔軟性がありません。
上記の問題を回避するには、ユニークで安全な塩を動的に生成することをお勧めします。ここにいくつかの重要なポイントがあります:
PHPのRandom_bytes()関数は、高強度のランダムバイトを生成でき、塩をBase64または同様のエンコーディングを組み合わせることで生成できます。
function generateSalt($length = 16) {
$bytes = random_bytes($length);
return substr(strtr(base64_encode($bytes), '+', '.'), 0, $length);
}
さまざまなアルゴリズムには、塩形式の要件が異なります。 SHA-512( $ 6 $ )を例として、形式は次のとおりです。
$6$rounds=5000$saltstring$
動的塩と組み合わせる:
$saltString = '$6$rounds=5000$' . generateSalt() . '$';
$hash = crypt($password, $saltString);
Cryptによって返されるハッシュには、塩情報が含まれています。保管するときは、塩を個別に保存せずに完全なハッシュを保存するだけです。
検証するときは、入力パスワードとストレージハッシュでCryptを直接呼び出し、結果を比較してください。
function verifyPassword($inputPassword, $storedHash) {
return crypt($inputPassword, $storedHash) === $storedHash;
}
<?php
// 動的塩を生成します
function generateSalt($length = 16) {
$bytes = random_bytes($length);
return substr(strtr(base64_encode($bytes), '+', '.'), 0, $length);
}
// パスワードハッシュを作成します
function createHash($password) {
$salt = '$6$rounds=5000$' . generateSalt() . '$';
return crypt($password, $salt);
}
// パスワードを確認します
function verifyPassword($inputPassword, $storedHash) {
return crypt($inputPassword, $storedHash) === $storedHash;
}
// 使用の例
$password = 'mypassword123';
$hash = createHash($password);
echo "ハッシュ値: $hash\n";
if (verifyPassword('mypassword123', $hash)) {
echo "パスワード検証が成功しました!\n";
} else {
echo "パスワード検証に失敗しました!\n";
}
?>
ハードコーディングされた塩値を回避すると、パスワードハッシュのセキュリティが大幅に向上する可能性があります。 PHPの乱数生成関数を使用することにより、一意の塩値が動的に作成され、完全なハッシュがデータベースに保存され、さまざまな攻撃方法に効果的に抵抗できます。