PHPでは、 Crypt()関数は暗号化に使用される従来の方法の1つです。複数のアルゴリズム(DES、MD5、SHA-256、SHA-512など)をサポートし、UNIXシステムの暗号化形式と互換性があります。多くのアプリケーションでは依然として役割を果たしていますが、開発者は、高い並行性シナリオでcrypt()関数を使用する場合、パフォーマンスのボトルネックとセキュリティリスクに特別な注意を払う必要があります。
Crypt()はさまざまな暗号化アルゴリズムをサポートしており、そのパフォーマンスの違いは膨大です。たとえば、SHA-512は一般にDESおよびMD5よりも安全ですが、より時間がかかります。高い並行性では、各ユーザー要求はパスワード検証を1回実行します。各暗号化操作に長い時間がかかる場合、大量のCPUリソースをすぐに占有し、要求の蓄積、応答の遅延、さらにはサーバーダウンタイムになります。
たとえば、制御された負荷の下でアルゴリズムベンチマークを実行することをお勧めします。
$hash = crypt('password123', '$6$rounds=5000$usesomesillystringforsalt$');
ここでの$ 6 $は、SHA-512を使用することを意味し、さらにラウンドパラメーターは暗号化の複雑さを制御できますが、速度にも大きく影響します。サーバーのハードウェアと並行性に基づいて合理的にラウンドを設定することをお勧めします。
暗号化アルゴリズムの塩値は、虹のテーブル攻撃を防ぐための鍵です。 Crypt()では、ユーザーが手動で塩を提供する必要があります。これにより、複数のユーザーが同じ塩を使用するとセキュリティが減ります。塩値を自動的に生成する場合、それらが十分にランダムであることを確認してください。
$salt = '$6$' . bin2hex(random_bytes(16)) . '$';
$hash = crypt('password123', $salt);
最新の暗号化セキュリティ要件を満たすランダム_bytes()などの関数を使用して塩値を生成すると、全体的なセキュリティが大幅に改善される可能性があります。
Crypt()自体はスレッドセーフですが、ユーザーのパスワード検証に特定のバックエンド共有リソース(データベースやキャッシュシステムなど)を使用する場合、Apache MPMワーカーモードやPHP-FPMの同時実行スクリプトを使用するなど、高電流PHPアプリケーションでは、暗号化操作は後期プロセスを回避する必要があります。推奨されるアプローチは、 Crypt()を非同期プロセスまたは別のマイクロサービスに配置して、メインビジネスプロセスのブロックを避けることです。
// 擬似コードの例
$input = $_POST['password'];
$stored_hash = get_user_hash_from_db($user_id);
if (hash_equals($stored_hash, crypt($input, $stored_hash))) {
// 検証が合格しました
}
並行性のボリュームが非常に高い場合、論理電流制限にログインするか、キューシステムにアクセスすることを検討できます。
Crypt()はシンプルで使いやすいですが、そのスケーラビリティと構成性は、最新のWebシステムのセキュリティとパフォーマンスのニーズを満たすことができなくなりました。高い並行機関システムでは、より最新のインターフェイスであるPassword_hash()とpassword_verify()を使用することをお勧めします。
$hash = password_hash('password123', PASSWORD_DEFAULT);
// ストレージ $hash データベースに移動します
// パスワードを確認します
if (password_verify('password123', $hash)) {
// 正しいパスワード
}
password_hash()は、デフォルトでbcryptを使用します。 php> = 7.2 password_argon2iまたはpassword_argon2idを選択できます。これらのアルゴリズムは、耐衝撃防止攻撃に適しています。
さらに、Redisなどの短期キャッシュを使用して、データベースからユーザーハッシュ値の頻繁な読み取りを回避することも最適化方法です。
ポータルレベルのログインシステムやAPIゲートウェイなどの極端な並行シナリオでは、パスワード検証を専用の検証サービスまたはハードウェアアクセラレーションモジュールに水没させることができます。たとえば、次のアーキテクチャを設計できます。
フロントエンドPHPアプリケーションはリクエストを受け取ります。
次のような内部インターフェイスを介して、ユーザー名とパスワードをパスワード検証サービスに送信します。
POST http://auth.m66.net/verify
{
"username": "jdoe",
"password": "password123"
}
バックエンドサービスは、より効率的な言語(GOや錆など)で実装できるパスワード検証を担当し、暗号化パラメーターとキャッシュメカニズムが統一されています。
Crypt()関数は依然として実用的ですが、同時性の高いアプリケーションのパフォーマンスボトルネックになる可能性があり、それを使用する方法についても高い要件があります。システムの安定性とセキュリティを確保するために、暗号化アルゴリズムの選択、塩価値戦略、スレッド環境、およびサービスアーキテクチャを包括的に考慮し、 Password_hash()や専用の検証サービスなどのプロジェクトスケールに応じて、より最新のパスワード処理メカニズムを採用する必要があります。
合理的な設計により、安全性を犠牲にすることなく、高電流シナリオでシステムを効率的に動作させることができます。