PHPでは、 Crypt()関数はパスワードをハッシュする関数であり、異なる暗号化アルゴリズムに基づいて暗号化された文字列を生成します。多くの開発者は、認証またはトークンメカニズムを実装する際に、Crypt()関数によって生成されたハッシュ値をトークンとして使用することを検討する場合があります。それで、 crypt()によって生成されたハッシュ値をトークンとして安全に使用できますか?この記事ではこれを分析します。
Crypt()関数の基本的な使用法は次のとおりです。
$hash = crypt($password, $salt);
$パスワードは、暗号化する必要がある文字列(通常はパスワード)です。
$塩は、ハッシュの独自性とセキュリティを高めるために暗号化に必要な「塩」です。
渡された塩パラメーターによると、 Crypt()は、DES、MD5、BlowFish( $ 2A $で始まる)などの異なる暗号化アルゴリズムを選択します。
安全なトークンは、次の条件を満たす必要があります。
一意性:さまざまなリクエストによって生成されたトークンは、リプレイ攻撃を防ぐために異なるはずです。
予測不可能性:攻撃者は、既知のトークンを介して他のトークンを推測することはできません。
十分な長さと複雑さ:ブルートフォースの亀裂が困難になることを保証します。
偽造を防ぐ:簡単に偽造したり改ざんしたりすることはできません。
Crypt()の主な目的は、パスワードを一方向にハッシュすることです。ハッシュ結果はパスワードダイジェストを安全に保存しますが、次の理由でトークンを生成するのに完全には適していません。
Crypt()は同じ入力と塩を使用し、同じハッシュ値を生成します。パスワードを入力として直接使用し、塩が変化しないままにすると、トークンが固定されます。これは、一意で変化するトークンを生成するのに役立ちません。
塩がうまく設計されていない場合、トークンが予測可能であり、攻撃者によって推測または再利用される可能性があります。
これにより、トークンはさまざまなセッションやリクエストで再利用され、適時性が失われます。
トークンのセキュリティを確保するために、次の方法を推奨します。
PHPは、random_bytes()またはbin2hex(random_bytes($ length))を使用して、高強度のランダム文字列を生成できます。
$token = bin2hex(random_bytes(32)); // 64ビット長のランダムな文字列
hash_hmac()を使用して、ランダム文字列を暗号化して、トークンの完全性と非焦点を確保します。
$secret_key = 'your_secret_key';
$random_string = bin2hex(random_bytes(16));
$token = hash_hmac('sha256', $random_string . time(), $secret_key);
JSON Webトークン(JWT)などの標準ライブラリは、ユーザー情報や有効期限を含む安全なトークンを生成し、署名を検証できます。
Crypt()関数によって生成されるハッシュ値は、主にパスワードストレージに適しており、トークンとして直接使用するのに適していません。
その出力には、ランダム性と適時性がありません。
トークンを固定して予測可能にするのは簡単です。
塩の値の管理は複雑で、動的なトークンの生成には不便です。
したがって、安全でユニークなトークンを生成するために、特別な乱数関数と署名アルゴリズムを使用することをお勧めします。