私はこれらの2つの質問で提示された概念について読みました:
パスワードの長さの制限を避けるためにbcryptを適用する前にパスワードを事前にハッシュする
BcryptとPBKDF2を一緒に使用するのは理にかなっていますか?
私は、両方の質問で提示された概念を組み合わせた実装を思いついたと思いますが、場合によってはいくつかのセキュリティ層を提供します。
アルゴリズム
SHA-512, bcrypt, PBKDF2
パブリックソルト
public_salt
プライベートペッパー
email_pepper, bcrypt_pepper, pbkdf2_pepper
ユーザーグローバル
public_salt, email_pepper
ユーザー固有
bcrypt_pepper, pbkdf2_pepper
email_key = PBKDF2(email, public_salt)
password_key = PBKDF2(password, public_salt)
POST: keys -> SSL -> server
stored_email_key = PBKDF2(email_key, email_pepper)
server gets bcrypt_pepper, and pbkdf2_pepper
reduced_hash = SHA-512(password_key)
bcrypt_hash = bcrypt(reduced_hash, bcrypt_pepper)
pbkdf2_hash = PBKDF2(bcrypt_hash, pbkdf2_pepper)
Password - pbkdf2(bcrypt(sha512(pbkdf2(password, public_salt)), bcrypt_pepper), pbkdf2_pepper)
Email address - pbkdf2(pbkdf2(email_address, public_salt), email_pepper)
これはやり過ぎかもしれませんが、パスワードとメールアドレスが適切に処理および保存されていることを確認したいと思います。
プロセスの各ステップの反復回数にどの値を使用するかについては、まだ議論中です。明らかに、私はjavascriptよりもサーバー上でより多くの反復を使用するつもりです。
PBKDF2を使用する1024ビットのキーを生成することと、2048ビット以上のソルトを使用することを考えています。
セキュリティの最初のルールは次のとおりです:独自の暗号をロールしないでください。
あなたは複雑なスキーマを思いついたが、それはベストプラクティスよりも実際には何も改善しない。また、ソルトやペッパーとは何か、なぜそれらが使用されるのかについてもわかりません。ソルトは固定長のバイトのランダムなセットであり、秘密とは見なされません。コショウは(秘密の)鍵です。
クライアント側のハッシュ
クライアント側で値をハッシュしても、次の理由で何も得られません。
メールアドレス
ユーザーと通信するために後で必要になるため、通常はユーザーのメールアドレスをリバーシブル/読み取り可能な形式にする必要があります。派生値しかない場合は、連絡できません。
事前にハッシュされたパスワード
BCryptは、パスワードを55バイトの入力に切り捨てます( salt を除く)。一般的に引用されている128ビット、256ビット、さらには1024ビットの値を考慮すると、55バイトはそれほど多くないように思われるかもしれません。ただし、一般的なパスワードは、6〜10文字の範囲の長さの現実です。
より長い値を許可したい場合は、単に使用します
bcrypt(sha512($password));
*
コショウの値はここで議論されています の必要性。コショウとソルトの両方を使用してパスワードを保存する場合は、次を使用します。
bcrypt(hash_hmac('sha256', $password, $pepper));
*
推奨されるように ここ 。
*)どちらの例でも、ソルトを自動的に作成するBCrypt実装を使用していると想定しています。