私の質問の抽象的な表現は次のようになります:
byte[] encrypted = AES.Encrypt(bytesToEncrypt, password);
byte[] hash = SHA256.Hash(password);
攻撃者がencrypted
とhash
の両方の値を取得した場合、どちらか一方しかなかった場合には得られないであろう利点を彼らに与えるのですか?
これは安全ですifパスワードが安全です。たとえば、パスワードとしてランダムに生成された16バイトは問題ありません。または、bcrypt、scrypt、argon2などの優れた鍵導出関数(KDF)を介して実行された強力なパスワード(遅いほど良いので、攻撃者は推測しかできません)遅い速度で)。
攻撃者により多くの情報を提供するため、より多くの情報を提供することはほぼ避けられません。考えられることは2つあります。
いずれか誰かがSHA2で プリイメージ攻撃 を見つけた場合、スキームは壊れます、または誰かが何らかの攻撃を見つけた場合AESでは、キーの回復につながります。
攻撃者がハッシュのみを持ち、暗号化されたコンテンツを持たない場合、AESへの攻撃を使用してハッシュを解読することはできません(逆も同様です)。
ただし、AESまたはSHA2を完全に破壊する攻撃はほとんどありません。どちらのアルゴリズムも非常によく研究されており、通常、最初にアルゴリズムを大幅に劣化させることでクラッキングが発生します。これらの2つのうちどちらかが壊れていると、とにかくかなり大きな問題が発生します。
encrypted
バイトをクラックすると、不正な試行が行われるたびに攻撃者がランダムなゴミを出力として取得します。入力(bytesToEncrypt
)もランダムと区別がつかない場合(たとえば、ビットコイントランザクションIDの場合)、攻撃者が正しい答えをいつ得たかは決してわかりません。 (まあ、おそらく彼らは歴史のすべてのビットコイン取引をチェックして、一致するものを見つけることができます...しかし、あなたはアイデアを得ます。)
代わりに、ハッシュに対応する入力を見つけることができます。それが見つかると、答えが正しいことがわかり、それを使用してメッセージを復号化できます。
ただし、通常は、復号化が正しいことを確認できるため、これは小さな利点にすぎません。そして、これはあなたのパスワードがそもそも推測できることを前提としています。
言ったように、両方とも非常にありそうもない/実行不可能です。 password
入力が安全な場合。ランダムな16バイト、または非常に強力でKDFされたパスワード。
したがって、スキームは基本的に安全ですが、それは大きなアプリケーションのほんの一部にすぎません。これが重要なアプリケーションである場合は、正しく実装されていることを確認するために、専門家によるレビューが必要です。 (注:これは、コードレビューフォーラムなどで尋ねるだけでなく、誰かに支払うことを意味します。)
また、AESおよびSHA2への入力を「パスワード」と呼び、ユーザー指定であることを意味します。投稿したコードではKDFが表示されないため、追加する必要があります。 bcrypt、scrypt、argon2などの遅いKDFを使用します。