データベース内のユーザーのすべてのパスワードを更新する必要がありますか? ログイン スクリプトをいじっても、何もする必要はありません。これを見てください:
Md5 パスワード ハッシュを BCRYPT ハッシュに更新しています::
$passwordFromDatabase = "0d107d09f5bbe40cade3de5c71e9e9b7"; // md5 hash of "letmein"
$passwordFromForm = $_POST['password']; // $_POST['password'] == "letmein"
if(password_needs_rehash($passwordFromDatabase, PASSWORD_BCRYPT, ["cost" => 12]) && md5($passwordFromForm) === $passwordFromDatabase){
// generate new password
$newPasswordHash = password_hash($passwordFromForm, PASSWORD_BCRYPT, ["cost" => 12]);
// update hash from database - replace old hash $passwordFromDatabase with new hash $newPasswordHash
// after update login user
if(password_veryfi($passwordFromForm, $newPasswordHash)){
// user has logged in successfully and hash was updated
// redirect to user area
}else{
// ups something went wrong Exception
}
}else{
if($password_veryfi($passwordFromForm, $passwordFromDatabase)){
// user password hash from database is already BCRYPTed no need to rehash
// user has logged in successfully
// redirect to user area
}else{
// wrong password
// no access granted - stay where you are
}
}
上記の例は普遍的です。それ以外の
... && md5($passwordFromForm) === ...){
保存されたパスワードに対して行ったネストされたハッシュの組み合わせを使用できます。いずれにせよ、最終的には BCRYP ハッシュになります。暗号化とセキュリティ、およびユーザー パスワードをハッシュするためのコスト パラメーターの正しい値を定義する方法については、以下をお読みください。
遅いアルゴリズム
現在の標準は、低速ハッシュ アルゴリズムを使用することです。PBKDF2、bcrypt、または scrypt はすべて、入力としてパスワードとソルトの両方を受け取り、構成可能な作業係数を使用します。この作業係数は、サーバーのハードウェアへのログイン時にユーザーが受け入れるだけ高く設定してください。参照
- PBKDF2は単純に反復処理された高速ハッシュです (つまり、効率的に並列化できます)。(これは、さまざまな基本アルゴリズムで使用できるスキームです。システムで使用しているアルゴリズムを使用してください。)
- Bcryptはいくらか (4KB) の作業メモリを必要とするため、プロセッサあたりのキャッシュが 4KB 未満の GPU では効率的に実装できません。
- Scryptは処理時間に加えて (構成可能な) 大量のメモリを使用するため、GPU やカスタム ハードウェアでの並列化には非常にコストがかかりますが、「通常の」コンピュータには通常十分な RAM が用意されています。
良いパスワード
パスワードの長さは 8 文字以上で、少なくとも 1 つを使用する必要があります。
大文字と小文字、および特殊文字を含む 8 文字の長さのパスワードを設定すると、6 634 204 312 890 625 の組み合わせを作成できます。ただし、パスワードが 1 週間である場合、たとえば 6 文字の小文字のみを使用すると、308,915,776 の組み合わせしか得られません。アカウントを安全にするために、パスワードの長さは 12 文字以上にすることをお勧めします。パスワードの組み合わせ数シミュレーターはこちら
CRACKING SPEED (クラッカーが GPU の処理能力を向上させたり、クラウド コンピューティングをより強力にしたりするために、毎年変更されます)
パスワードを設計するときは、将来の処理能力の向上と、ハッカーが入手するツールについて考えてください。
このプログラム IGHASHGPU v0.90 は、単一の ATI HD5870 GPU で毎秒約 13 億回の SHA-1 ハッシュ (つまり、2^30 以上) を実行できると主張しています。
40 ビットのエントロピーのパスワードを想定すると、これには 2^10 秒、つまり約 17 分かかります。
エントロピーが 44 ビットのパスワード (有名な XKCD コミックのパスワードなど) は 68 分かかります (最悪の場合、平均的な場合はこの半分です)。
複数の GPU で並列に実行すると、これが比例して高速化されます。
したがって、高速ハッシュを使用した総当たり攻撃は、理論上の危険ではなく、実際の危険です。また、多くのパスワードはエントロピーがはるかに低いため、総当たり攻撃がさらに高速になります。参照
解決
コストを操作することで、アルゴリズムの速度をカスタマイズできます。コストが高いほど、パスワードのコーディングとエンコードに時間がかかります。攻撃者がパスワードをブルート フォース攻撃するのを非常に困難にするために、おそらく約 500 ml を目標とするのが最善でしょう。
12 文字以上のパスワード + 低速のアルゴリズムは、パスワードがクラックされる前にブルート フォース攻撃を受ける適切な量の組み合わせを保証します。まともなパスワードを取得すると、パスワードの検証プロセスが非常に困難になり、時間/リソースを消費するものになるまで遅くすることで、システムに侵入しようとする誰かの生活をはるかに困難にすることができます. コストを、ユーザー パスワードの確認にかかる約 0.5 秒の時間に影響する数値に設定します。
コスト値をカスタマイズ
スクリプトの実行は処理能力とトラフィックに基づいてサーバーごとに異なるため、コストをどれくらい高く設定する必要があるかをどのように判断しますか?
検証プロセスにかかる時間を測定し、適切なコストに合わせてカスタマイズする必要があります。
<?php
/**
* This code will benchmark your server to determine how high of a cost you can
* afford. You want to set the highest cost that you can without slowing down
* you server too much. 8-10 is a good baseline, and more is good if your servers
* are fast enough. The code below aims for ≤ 50 milliseconds stretching time,
* which is a good baseline for systems handling interactive logins.
*/
$timeTarget = 0.50; // 500 milliseconds
$cost = 8; //start to measure from cost = 8
do {
$cost++;
$start = microtime(true);
password_hash("Ajd_hsk-K87&", PASSWORD_BCRYPT, ["cost" => $cost]);
$end = microtime(true);
} while (($end - $start) < $timeTarget);
echo "Appropriate Cost Found: " . $cost . "\n";
?>
参照
上記の関数は、安全要件を満たすために使用する必要があるコストの X 数を返します。
Appropriate Cost Found: 13 //this result will be different based on your server machine.
このスクリプトは、php マニュアルから取得され、10 倍長く処理するように拡張されています。ほとんどの場合、これは一般的に安全な方法ですが、管理者およびスーパー管理者のログインについては、実際のハッカーにとってより興味深い場所であるため、さらに時間のかかる (約 1 秒) ようにすることを検討します。