現在の位置: ホーム> 最新記事一覧> 虹のテーブル攻撃を防ぐためにPHPのCrypt()機能を正しく使用する方法は?

虹のテーブル攻撃を防ぐためにPHPのCrypt()機能を正しく使用する方法は?

M66 2025-07-10

最新のWeb開発では、ユーザーパスワードの安全なストレージが重要なタスクです。 Rainbow Table Attackは、元のパスワードをすばやく一致させるために、事前に計算されたハッシュテーブルに依存する一般的なパスワードクラッキング手法です。この攻撃から効果的に防御するには、パスワードハッシュに「塩」を追加する必要があります。 PHPのCrypt()関数は、この課題をうまく処理できるツールですが、正しく使用されている場合のみです。

1。Crypt()関数の紹介

PHPのCrypt()関数は、片道で文字列を暗号化するために使用され、パスワードハッシュによく使用されます。従来のDES、MD5、より安全なブローフィッシュ( $ 2Y $ )およびSHA-256 /512( $ 5 $ / $ 6 $ )など、さまざまな暗号化アルゴリズムをサポートしています。

関数プロトタイプは次のとおりです。

 string crypt(string $string, string $salt);

ここで、 $文字列は暗号化される元の文字列である場合、 $ SALTは使用するアルゴリズムと暗号化バリアントを決定します。

2.なぜcrypt()が虹のテーブル攻撃を防ぐことができるのですか?

レインボーテーブル攻撃は、ハッシュ値の事前計算に依存しています。ただし、各ハッシュの塩値が異なる場合、攻撃者は一致するために一般的なレインボーテーブルを使用できません。 crypt()を使用すると、塩値をカスタマイズでき、強力な暗号化アルゴリズムと組み合わせることで、この攻撃を効果的に回避できます。

たとえば、このようなブローフィッシュアルゴリズムと動的塩値を使用できます。

 $password = 'user-password';
$salt = '$2y$10$' . substr(strtr(base64_encode(random_bytes(16)), '+', '.'), 0, 22);
$hash = crypt($password, $salt);

上記のコードで:

  • $ 2Y $ 10 $は、コスト係数が10のBlowFishアルゴリズムを使用することを意味します。

  • random_bytes(16)は、高強度のランダム塩を生成します。

  • substr(...、0、22)は、ブローフィッシュ塩の形式に適合する長さにカットされます。

この方法で生成される$ハッシュは、塩を追加した後のパスワードハッシュです。

3.パスワードを確認するときにcrypt()の使用方法

ユーザーがログインすると、塩を手動で生成する必要はありませんが、データベースに塩パラメーターとして保存されているハッシュを使用してcrypt()に直接渡す必要はありません。

 $inputPassword = 'user-input';
$storedHash = '$2y$10$qzWRzYy5q3DvYbEC0KMX4O0PGWlOQxkz7v0QF5OwMqpyG0TzjSAGK'; // データベースから

if (hash_equals($storedHash, crypt($inputPassword, $storedHash))) {
    echo '正しいパスワード';
} else {
    echo 'エラーパスワード';
}

このようにして、 Crypt()は、ハッシュの塩とアルゴリズムを使用してパスワードを自動的に再クリックし、それを比較します。この方法はシンプルで安全です。

4.推奨されていない慣行と落とし穴

固定塩値を使用します

$hash = crypt($password, 'fixedsalt');

この方法は、同じパスワードが常に同じハッシュに対応するため、レインボーテーブル攻撃に対して非常に脆弱です。

古いアルゴリズム(DESなど)を使用する

$hash = crypt($password, 'ab'); // DES アルゴリズム,短すぎる塩

DESは塩が短いだけでなく、計算コストも低く、最新のハードウェアは簡単にブルートフォースクラックを獲得できます。

5。さらなる提案

Crypt()は安全ですが、PHPは5.5から始まるより最新のパスワードハッシュAPIであるPassword_hash()password_verify()を使用することをお勧めします。ただし、古いプロジェクトを維持している場合、または互換性の理由でCrypt()を使用している場合は、次のことを確認してください。

  • 強力なアルゴリズムを使用します( $ 2Y $$ 5 $$ 6 $など)。

  • 常にランダムで十分な塩値を使用してください。

  • 塩を再利用しないでください。

  • 塩の値は、個別に保管されるのではなく、ハッシュに保存する必要があります。

6。例:登録を完了し、ログインプロセスを完了します

// 登録するとき
$password = $_POST['password'];
$salt = '$2y$12$' . substr(strtr(base64_encode(random_bytes(16)), '+', '.'), 0, 22);
$hash = crypt($password, $salt);
// ストレージ $hash データベースに移動します

// ログインするとき
$inputPassword = $_POST['password'];
$storedHash = getHashFromDatabase(); // データベースから取得します

if (hash_equals($storedHash, crypt($inputPassword, $storedHash))) {
    echo '正常にログインします';
} else {
    echo 'エラーパスワード';
}

https://m66.net/php-crypt-guideにアクセスして、このチュートリアルのオンラインバージョンをより多くの例で入手できます。

結論

Crypt()関数の正しい使用は、虹のテーブル攻撃を効果的に防ぐことができます。重要なのは、比較時に強力な暗号化アルゴリズム、ランダム塩値、セキュリティ慣行を使用することです。新しいプロジェクトでは、Password_hash()シリーズの関数を使用することを推奨していますが、 Crypt()の安全な使用法を習得することも、すべてのPHP開発者にとって強制コースです。