PHPでは、 Crypt()はハッシュ暗号化の関数であり、パスワード処理とデータ暗号化のシナリオで広く使用されています。ただし、多くの開発者は、Crypt()関数を使用して同じコンテンツを暗号化するときに驚いています。
この記事では、この現象の背後にある理由を深く理解し、 Crypt()を正しく安全に使用する方法を教えてくれます。
Crypt()の本質はハッシュ関数であり、データを暗号化するためではなく、パスワード検証に使用されることが多い不可逆的なハッシュ値を生成するためです。
関数プロトタイプは次のとおりです。
string crypt(string $string, string $salt)
2つのパラメーターを受け取ります。
$文字列:暗号化される文字列。
$塩:暗号化中に使用される「塩値」。ハッシュ結果に影響を与えるために使用されます。
同じ$ SALTを渡すと、同じ$文字列を暗号化すると同じ結果が得られます。これがまさに、「暗号化の結果が常に同じである」と思う理由です。
これは、 crypt()を呼び出すと、固定塩値を使用するか、2番目のパラメーター$塩を単に渡した可能性があるためです。
PHPのcrypt()は、 $塩が提供されない場合にシステムのデフォルトメカニズムを使用しようとしますが、このメカニズムは一部のシステムで「デフォルトで同じ塩を使用する」と表示される場合があり、「同じ入力が常に同じ出力を取得します」となります。
次の例を見てください。
echo crypt("mypassword", "m6"); // 固定を使用します salt
このコードを実行するたびに、出力は何回でも同じになります。これは、攻撃者が固定塩を使用していることを知っている場合、ハッシュテーブルを事前に計算してシステムを攻撃することもできます。
**正しい方法は、ランダム塩値を使用します。 **ユーザーにパスワードハッシュが生成されるたびに、別の塩が生成され、データベースに保存されます。これにより、2人のユーザーのパスワードが同じであっても、ハッシュ値は異なります。
PHPは、Php 5.5+から導入されたより安全な方法であるPassword_hash()関数を使用するなど、自動塩生成を使用した方法を使用することをお勧めします。
$password = 'mypassword';
$hash = password_hash($password, PASSWORD_BCRYPT);
この関数は、あなたのためにユニークな塩を自動的に生成し、結果に取り付けます。各実行は異なる結果が得られます:
// 各出力は異なります
$hash1 = password_hash('mypassword', PASSWORD_BCRYPT);
$hash2 = password_hash('mypassword', PASSWORD_BCRYPT);
ただし、 Password_verify()を使用して元のパスワードを確認するために使用できます。
Crypt()を使用する必要がある場合は、ランダム塩を手動で生成します。これが例です:
function generate_salt($length = 22) {
return substr(strtr(base64_encode(random_bytes($length)), '+', '.'), 0, $length);
}
$password = 'mypassword';
$salt = '$2y$10$' . generate_salt(); // 使用 Blowfish アルゴリズム
$hash = crypt($password, $salt);
各呼び出しは異なる塩を生成し、自然に異なる暗号化の結果が生成されます。
暗号化された結果は、その後の検証のためにデータベースに保存する必要があります。サンプルコードは次のとおりです。
// ストレージの場合
$hash = crypt($password, $salt);
// データベースに保存します
// 検証中
if (hash_equals($hash, crypt($inputPassword, $hash))) {
echo "パスワードを修正します";
} else {
echo "エラーパスワード";
}
Crypt()の2番目のパラメーターは、暗号化されたハッシュ値に直接渡すことができ、PHPはそこから塩を自動的に抽出することに注意してください。
Crypt()は、同じ塩を使用したため、同じ結果を返します。
安全にするには、ランダムソルトを使用するか、 password_hash()を直接使用する必要があります。
特別な要件がない限り、新しいプロジェクトでcrypt()を継続することはお勧めしません。
虹色のテーブル攻撃を防ぐために、ハードコーディングされた塩を常に避けてください。
ユーザーのパスワード処理を含むシステムを開発する場合、セキュリティは常に最優先事項です。 Crypt()の動作を正しく理解することで、より安定した信頼性の高いアプリケーションシステムを構築するのに役立ちます。