ユーザーの財務データをデータベースに格納する必要があるプライベートプロジェクトに取り組んでいます。このデータをAESを使用して暗号化し、さらにscryptを使用して、より単純なユーザーパスワードからAES暗号化キーを生成します。
また、ログイン時に正しいパスワードを使用しているかどうかをユーザーに通知できるようにしたいと思います。速度は問題ではありません。プログラムは、マルチユーザーサーバーではなくユーザーのデバイスで実行されます。
要約すると、データの暗号化とユーザーの認証の両方に1つのパスワードを使用したいと思います。
これを行うには2つのオプションがあります。
Scrypt出力からSHA-256ハッシュを生成し、そのハッシュをStoredHashに格納し、SHA256(scrypt( "supplied password"))== StoredHashかどうかを確認します。
鍵としてscrypt-outputを使用してEncryptedScryptOutputのAESを使用してパスワードのscrypt-outputを暗号化し、それを格納して、scrypt( "supplied password")== AESdescrypt(decryptionKey = scrypt( "supplied password")、EncryptedScryptOutput)かどうかを確認します。 。
私(I :-)は、塩や初期ベクトルを使用して、これを行う技術的な方法を認識しています。私の質問は次のとおりです。両方のバージョンが安全になることは正しいですか? 1つのオプションが他のオプションよりも優れていると思いますか、そしてその理由は?
ありがとう!
どちらの方法も安全ですが、最初の方法をお勧めします。
最初の提案は、暗号化キーとしてscrypt(password)
を使用し、パスワード検証としてSHA256(scrypt(password))
を使用することです。これで結構です。 SHA256プレイメージを計算することは計算上不可能であるため、攻撃者がパスワード検証から暗号化キーを計算することは不可能です。
2番目の提案は、scrypt(password)
を暗号化キーとして使用し、AES(scrypt(password), scrypt(password))
をパスワード検証として使用することです。自身を暗号化するためのキーとして値を使用することはハッシュの形式であるため、SHA256を使用する代わりにAES(x、x)を使用してscrypt(password)
をハッシュすることを除いて、これは最初の提案と同じです。 SHA256は適切なハッシュ関数であり、AES(x、x)は最初の提案ではないため、推奨されます。
私が知る限り、あなたの計画はこれです:
scrypt(pass)
を計算し、認証キーとしてデータベースに保存します。sha256(scrypt(pass))
を計算し、それをデータ暗号化キーとして使用します。この手法の問題は、データベースにアクセスできる攻撃者がscryptハッシュのSHA256ハッシュを単純に計算して、暗号化キーを取得できることです。
より良い解決策は、データ暗号化キーとして2番目のscryptハッシュを使用し、代理キーを使用して簡単なパスワード変更を容易にすることです。
s1
_および_s2
_)を生成し、プレーンテキストで保存します。k
を生成します-これが代理キーです。scrypt(pass, s1)
を計算し、認証キーとしてデータベースに保存します。scrypt(pass, s2)
とxor k
を計算します。この値をデータベースに保存します。復号化するときは、scrypt(pass, s2)
を計算し、格納されたキー値でxorを実行して、k
の元の値を取得します。
これにより、データベースが侵害された場合から保護され、k
の元の値を計算し、新しいパスワードとソルトのscryptハッシュでxorすることにより、パスワードを変更できます。ユーザーがパスワードを忘れた場合、データを回復できないことに注意してください。