27

1) crypt() を使用してパスワードの安全な Blowfish ハッシュを作成するにはどうすればよいですか?

$hash = crypt('somePassword', '$2a$07$nGYCCmhrzjrgdcxjH$');

1a) 「$2a」の意味は何ですか? Blowfish アルゴリズムを使用する必要があることを示しているだけですか?
1b) 「$07」の意味は何ですか? より高い値は、より安全なハッシュを意味しますか?
1c) 「$nGYCCmhrzjrgdcxjH$」の意味は何ですか? これは使用する塩ですか?これはランダムに生成する必要がありますか?ハードコーディング?

2) フグのハッシュをどのように保存しますか?

echo $hash;
//Output: $2a$07$nGYCCmhrzjrgdcxjH$$$$.xLJMTJxaRa12DnhpAJmKQw.NXXZHgyq

2a) これのどの部分をデータベースに保存する必要がありますか?
2b) 列 (MySQL) にはどのデータ型を使用する必要がありますか?

3) ログインの試行をどのように確認する必要がありますか?

4

2 に答える 2

13

crypt の出力全体を保存する必要があります。どのような場合でも、ハッシュしているパスワードごとに新しいソルトを生成する必要があるため、分割する意味はあまりありません。Matt が述べたように、固定された非表示のソルトを使用するのは間違っています。ソルトはハッシュごとに異なる必要があります。

詳細については、http: //www.openwall.com/articles/PHP-Users-Passwords を参照してください。crypt() とは異なり、ランダムなソルトの生成を処理する phpass ライブラリを使用することをお勧めします。

于 2011-02-13T21:47:18.320 に答える
0

1a) 暗号化の強度 - 4..31 の範囲の要件。http://php.net/manual/en/function.crypt.phpを参照してください

1b) 1aを参照

1c) 1a を参照。「salt」はランダムであってはなりません。そうしないと、特定の入力に対して同じハッシュを再生成できなくなります - 3 を参照してください。

2a) 厳密に言えば、ハッシュを除くすべて (データベースが侵害された場合)。また、Web サーバーのドキュメント ルートの下にアクセスできないファイルにソルトを保存し、それを含めます。可能な限り厳格な権限で設定してください。理想的には、Web ホスト サービス (例: apache) に対して読み取り専用で、書き込み権限も実行権限もありません。厳密に言えば、ハッカーに対してどれだけ防御したいかによって異なります。塩を保管しないと、生活がより困難になります。アルゴリズムに入力されるデータを正しく取得する必要がありますが、なぜ簡単にする必要があるのでしょうか。

2b) ハッシュを保存しない場合、フグには VARCHAR(32) で問題ありません。

3) 適切なインジェクション防止コードなどを既に実行していると仮定します。したがって、以下を盲目的にコピーしないでください(理想的には、mysql 拡張機能の代わりに PDO を使用します)。以下はフグ、SHA-256、および SHA-512 に固有のもので、これらはすべてハッシュ内のソルトを返します。他のアルゴリズムには変更が必要です...

//store this in another file outside web directory and include it
$salt = '$2a$07$somevalidbutrandomchars$'

...

//combine username + password to give algorithm more chars to work with
$password_hash = crypt($valid_username . $valid_password, $salt)

//Anything less than 13 chars is a failure (see manual)
if (strlen($password_hash) < 13 || $password_hash == $salt)
then die('Invalid blowfish result');

//Drop the salt from beginning of the hash result. 
//Note, irrespective of number of chars provided, algorithm will always 
//use the number defined in constant CRYPT_SALT_LENGTH
$trimmed_password_hash = substring($password_hash, CRYPT_SALT_LENGTH);
mysql_query("INSERT INTO `users` (username,p assword_hash) VALUES '$valid_username', '$trimmed_password_hash'");

...

$dbRes = mysql_query("SELECT password_hash FROM `users` WHERE username = '$user_input_username' LIMIT 1");
//re-apply salt to output of database and re-run algorithm testing for match
if (substring($salt, CRYPT_SALT_LENGTH) . mysql_result($dbRes, 0, 'password_hash') ) ===
        crypt($user_input_username . $user_input_password, $salt) ) {
    //... do stuff for validated user
}
于 2011-02-13T12:01:36.440 に答える