web-dev-qa-db-ja.com

ユーザー認証+同じパスワードでのデータベース暗号化

ユーザーの財務データをデータベースに格納する必要があるプライベートプロジェクトに取り組んでいます。このデータをAESを使用して暗号化し、さらにscryptを使用して、より単純なユーザーパスワードからAES暗号化キーを生成します。

また、ログイン時に正しいパスワードを使用しているかどうかをユーザーに通知できるようにしたいと思います。速度は問題ではありません。プログラムは、マルチユーザーサーバーではなくユーザーのデバイスで実行されます。

要約すると、データの暗号化とユーザーの認証の両方に1つのパスワードを使用したいと思います。

これを行うには2つのオプションがあります。

  1. Scrypt出力からSHA-256ハッシュを生成し、そのハッシュをStoredHashに格納し、SHA256(scrypt( "supplied password"))== StoredHashかどうかを確認します。

  2. 鍵としてscrypt-outputを使用してEncryptedScryptOutputのAESを使用してパスワードのscrypt-outputを暗号化し、それを格納して、scrypt( "supplied password")== AESdescrypt(decryptionKey = scrypt( "supplied password")、EncryptedScryptOutput)かどうかを確認します。 。

私(I :-)は、塩や初期ベクトルを使用して、これを行う技術的な方法を認識しています。私の質問は次のとおりです。両方のバージョンが安全になることは正しいですか? 1つのオプションが他のオプションよりも優れていると思いますか、そしてその理由は?

ありがとう!

3
Jelle Veraa

どちらの方法も安全ですが、最初の方法をお勧めします。

最初の提案は、暗号化キーとしてscrypt(password)を使用し、パスワード検証としてSHA256(scrypt(password))を使用することです。これで結構です。 SHA256プレイメージを計算することは計算上不可能であるため、攻撃者がパスワード検証から暗号化キーを計算することは不可能です。

2番目の提案は、scrypt(password)を暗号化キーとして使用し、AES(scrypt(password), scrypt(password))をパスワード検証として使用することです。自身を暗号化するためのキーとして値を使用することはハッシュの形式であるため、SHA256を使用する代わりにAES(x、x)を使用してscrypt(password)をハッシュすることを除いて、これは最初の提案と同じです。 SHA256は適切なハッシュ関数であり、AES(x、x)は最初の提案ではないため、推奨されます。

4

私が知る限り、あなたの計画はこれです:

  • scrypt(pass)を計算し、認証キーとしてデータベースに保存します。
  • sha256(scrypt(pass))を計算し、それをデータ暗号化キーとして使用します。

この手法の問題は、データベースにアクセスできる攻撃者がscryptハッシュのSHA256ハッシュを単純に計算して、暗号化キーを取得できることです。

より良い解決策は、データ暗号化キーとして2番目のscryptハッシュを使用し、代理キーを使用して簡単なパスワード変更を容易にすることです。

  • 2つのソルト(_s1_および_s2_)を生成し、プレーンテキストで保存します。
  • 暗号で保護されたランダムキーkを生成します-これが代理キーです。
  • scrypt(pass, s1)を計算し、認証キーとしてデータベースに保存します。
  • scrypt(pass, s2)とxor kを計算します。この値をデータベースに保存します。
  • データ暗号化キーとして「k」を使用します。

復号化するときは、scrypt(pass, s2)を計算し、格納されたキー値でxorを実行して、kの元の値を取得します。

これにより、データベースが侵害された場合から保護され、kの元の値を計算し、新しいパスワードとソルトのscryptハッシュでxorすることにより、パスワードを変更できます。ユーザーがパスワードを忘れた場合、データを回復できないことに注意してください。

6
Polynomial