1

MySQLを使用してDjangoWebサイトを構築しています。ユーザーのパスワードを保存するために、ランダムに生成されたソルトハッシュを備えたDjangoの組み込みpbkdf2-sha256を使用することをすでに決定しました。

ただし、このWebサイトには、他の多くのWebサイト(oauthを使用しない)のサードパーティのログイン資格情報も保存する必要があります。そこで私はAES-256暗号化を検討していましたが、もちろん問題は暗号化キーを安全に保管する場所になります。

これが私の解決策です。各暗号化キー=ユーザーの実際のパスワードのハッシュとランダムに生成されたソルト(パスワードに保存されたハッシュにすでに使用されているソルトとは異なります)とします。ソルトはテーブルに保存されますが、実際のパスワードとそのハッシュは明らかに保存されません。したがって、暗号化キーはログイン時に生成され、一時的に保存されますが、ログアウト時に期限切れになります。さらに、サーバーを危険にさらす誰かが、元のpbkdf2-sha256ハッシュを解読せずに暗号化キーを生成することはできません。それでも、ユニバーサルキーではなく、その1人のユーザーのみが使用できます。

欠点は、パスワードを変更/リセットした場合、サイトごとに資格情報を再入力する必要があることです。しかし、それは大したことではなく、サーバーのどこかにキーを保存したり、別のサーバーに保存したりするよりもはるかに安全なようです。

しかし、私は24時間前にハッシュが何であるかを知っただけなので、私は何を知っていますか。私は何かを見落としていますか、それともこれはかなり安全ですか?それとももっと良い方法はありますか?

4

1 に答える 1

3

あなたが言及するアルゴリズムPBKDF2は、実際にはこの明示的な目的のために設計されています。

したがって、ワークフローはランダムなソルトを生成することです。次に、それをユーザーのデータベースに保存します。

反復回数が多いPBKDF2とソルトを使用して、640ビットのキーマテリアル(80バイト)を生成します。

最初の128ビットは暗号のIVになります

次の256ビットは暗号鍵(AES-256に使用される鍵)になります

最後の256ビットがMACキー(暗号化の認証に使用されるキー)になります。

key = PBKDF2-SHA256(password, salt, 50000, 80)
iv = key[0:128]
cipherKey = key[128:384]
macKey = key[384:640]

次に、これらのキー(擬似コード)を使用してデータを暗号化します。

ciphertext = AES-256-CBC(data, cipherKey, iv)
authtext = SHA256-HMAC(ciphertext, macKey)
result = '{}{}'.format(authtext, ciphertext)

さて、復号化の際は、逆に戻ってください...

key = PBKDF2-SHA256(password, salt, 50000, 80)
iv = key[0:128]
cipherKey = key[128:384]
macKey = key[384:640]

authtext = result[0:32]
ciphertext = result[32:]

if !timingSafeComparison(authtext, SHA256-HMAC(ciphertext, macKey)):
    return false

return AES-256-CBC-DECRYPT(ciphertext, cipherKey, iv)

はい、ユーザーがパスワードを忘れた場合、暗号化されたデータはすべて失われます。しかし、それはあなたが望むものですよね?

于 2013-06-21T18:18:52.193 に答える