ですから、始める前のちょっとしたコンテキストが便利かもしれません。 Java SQLiteデータベースを使用してデータを保存/処理するデスクトップアプリケーションを開発しています。アプリケーションは認証を使用して、データの編集、データの追加/削除などのプログラムにアクセスします。しかし、最初にWindowsへの認証を行わずに、攻撃者がラップトップのハードドライブを引き出してデータにアクセスできるようにしたくない。
私の質問は、say ... AES256を使用してSQLiteデータベースに挿入する前に特定のデータを暗号化した場合、ユーザーがパスワードを挿入しなくても、アプリケーションでパスワードをハードコーディングせずにデータを復号化できるかどうかです。ユーザーが2つのパスワード(1つはアプリケーション認証用、もう1つはデータベースの暗号化/復号化用)を覚えておかなければならないオーバーヘッドは、暗号化/復号化パスワードを忘れるとデータが失われるため、実行不可能だと思います。
あなたが共有したり、役立つかもしれないいくつかのアイデアを提案したりできるソリューションに出くわしたことがありますか?
ユーザーが最初にログインすると、ソフトウェアは新しいパスワードを要求します。この時点で、DBは空である必要があります。
これでUserPasswordと空のDBができました。したがって、ソフトウェアは新しいランダムDBdataKeyを生成します。これは、DBコンテンツの暗号化/復号化に使用されます。暗号化/復号化するには、AESなどの既知のアルゴリズムのいずれかを使用します。
次に、2つのランダムなソルト文字列を作成します:PasswordSaltおよびDBdataKeySalt。 PasswordSaltおよびDBdataKeySaltをクリアテキストとしてDBに保存します。
UserPasswordおよびDBdataKeySaltを指定してpbkdf2(またはSHA2以上のようなもの)のハッシュ関数を使用して、DBdataKeyEncryptionKey
今:DBdataKeyは、DBコンテンツの暗号化/復号化に使用するキーですDBdataKeyEncryptionKeyは、データベースの暗号化/復号化に使用するキーですDBdataKey
UserPasswordおよびPasswordSaltを使用してpbkdf2(またはSHA2以上のようなもの)のハッシュ関数を使用してHashedSaltedUserPassword、UserPasswordのソルトハッシュバージョン、次にDBdataKeyを使用して暗号化DBに保存する前に、HasedSaltedUserPasswordを使用します。
今後は、DBdataKeyを使用して、DBとの間でデータを暗号化/復号化できます。
ここで、ユーザーがアプリケーションを開いたときにパスワードを要求し、入力されたパスワードをDBdataKeySalt(これはクリアテキストに保存されています)と共に使用してDBdataKeyEncryptionKey、次に取得したDBdataKeyEncryptionKeyを使用してDBdataKeyを復号化するため、復号化DBdataKeyしてDBを読み取ります。
DBdataKeyを使用してHashedSaltedUserPasswordを復号化し、入力されたパスワードとPasswordSalt(これはクリアテキストで保存されます)は、ログイン情報が正しいことを再確認します。
ユーザーが間違ったパスワードを入力した場合、DBdataKeyEncryptionKeyを使用してDBdataKeyを復号化すると、復号化関数は別の値を提供します(ゴミ)。その(間違った)値を使用してHashedSaltedUserPasswordを復号化すると、ガベージ値が多くなり、ハッシュと一致しなくなります。
ユーザーがUserPasswordを変更した場合は、古いパスワードでDBdataKeyを復号化し、新しいパスワードで再暗号化するだけですただし、DBdataKeyは変更されないため、ユーザーがパスワードを変更するときにdbの内容を再暗号化する必要はありません。
参考:私は何も発明していません、これはよく知られている2つのテクニックの組み合わせです: