8

byte[]私のチームは、Javaで記述されたAndroidアプリケーションのコンテキストでバイナリデータ(として保存される)を暗号化するソリューションを開発する必要があります。暗号化されたデータはさまざまな方法で送信および保存されますが、その間、データの破損を排除することはできません。最終的には、別のAndroidアプリケーション(これもJavaで記述されています)がデータを復号化する必要があります。

暗号化アルゴリズムは、256ビットのキーを持つAESでなければならないことがすでに決定されています。ただし、どのAES実装および/または「モード」を使用するかについて、十分な情報に基づいて決定したいと思います。私はGCMモードと呼ばれるものについて読み、それを使っていくつかのテストを行いました(BouncyCastle / SpongyCastleを使用)が、AES-GCMが正確に何のためにあり、プレーンと比較して何を「購入」するのかは完全にはわかりません。 AES-考慮すべきトレードオフがあるかどうか。

これが私たちが持っている懸念/要件/質問のリストです:

  • パディング:暗号化する必要のあるデータは常に128ビットの倍数になるとは限らないため、AES実装/モードではパディングを追加する必要がありますが、必要な場合に限ります。によって提供されるような単純なAES実装でjavax.crypto.Cipherはそれができないという印象を受けましたが、初期のテストではそうなることが示されました。したがって、パディング要件自体は、「プレーンな」AESではなくGCMのようなものに頼る理由にはならないのではないかと思います。あれは正しいですか?

  • 認証:データ破損が発生したかどうかを確実に検出する方法が必要です。ただし、理想的には、誤ったキーを使用して復号化が試行された場合も検出する必要があります。したがって、これらの両方のケースを区別できるようにする必要があります。私が最初にGCMを検討することになった理由は、このStackoverflowの質問によるものでした。回答者の一人は、詳細な説明(コードは言うまでもなく)を提供していませんが、AES-GCMを使用してこの区別を行うことが可能であると示唆しているようです。 。

  • オーバーヘッドの最小化:暗号化されたデータの保存と送信のオーバーヘッドを制限する必要があります。したがって、特定のAES実装/モードの選択がオーバーヘッドの量に影響を与えるかどうか、およびどの程度影響するかを知りたいと思います。

  • 暗号化/復号化のパフォーマンス:主要な懸念事項ではありませんが、特定のAES実装/モードの選択が、CPU時間とメモリフットプリントの両方の観点から、暗号化と復号化のパフォーマンスにどの程度影響するか疑問に思っています。

アドバイス、説明、コード例を事前に感謝します。

編集: delnanは、「プレーンAES」のようなものは存在しないことを有益に指摘しました。つまり、明確にするために、Javaの組み込みAESサポートを使用することを意味しました。
そのようです:Cipher localCipher = Cipher.getInstance("AES");

4

1 に答える 1

10

深刻な互換性の問題がない限り、2012年の答えはGCMを採用することです。

GCM認証付き暗号化モードです。機密性(暗号化)、整合性、および認証(MAC)を一度に提供します。

これまでのところ、通常の動作モードはECB(Javaのデフォルト)、CBC、CTR、OFB、およびその他のいくつかです。それらはすべて暗号化のみを提供しました。ただし、機密性自体が完全性なしで役立つことはめったにありません。このようなクラシックモードと整合性チェックをアドホックな方法で組み合わせる必要がありました。暗号化を正しく行うのは難しいため、そのような組み合わせは安全でないか、必要以上に遅いか、またはその両方であることがよくありました。

認証付き暗号化モードは、その問題を解決するために暗号学者によって(かなり最近)作成されました。GCMは、最も成功しているものの1つです。NISTによって選択され効率的で、特許がなく、追加の認証済みデータ(つまり、明確な状態を維持しながら、信頼性を検証できるデータ)を伝送できます。 。他のモードの説明については、MatthewGreenのこの優れた記事を参照してください。

あなたの懸念に来る:

  • パディング:デフォルトでは、JavaはPKCS#7パディングを使用します。それは機能しますが、 MACで打ち負かすのが最善のオラクル攻撃のパディングに対して脆弱であることがよくあります。GCMにはすでにMAC(GMACと呼ばれる)が組み込まれています。

  • 認証: AES-GCMは、パスワードではなく、1つのAESキーのみを入力として受け取ります。AESキーが間違っているか、ペイロードが改ざんされているかがわかりますが、そのような条件は1つとして扱われます。代わりに、 PBKDF2bcryptなどの適切な鍵導出アルゴリズムを使用して、パスワードからAES鍵を導出することを検討する必要があります。パスワードを確認するために必要なデータは常に破損している可能性があるため、パスワードが間違っているのか、ペイロードが変更されているのかを常に判断できるとは限りません。既知の小さな文字列を(ECB AESを使用して)暗号化し、送信して、パスワードが正しいかどうかを確認するために使用できます。

  • オーバーヘッドを最小限に抑える:認証が必要な場合、1日の終わりに、すべてのモードで同じオーバーヘッド(約10〜20バイト)が発生します。非常に小さなペイロードで作業している場合を除いて、この点は無視できます。

  • パフォーマンス: GCMは、オンラインモード(ペイロード全体をバッファリングする必要がないため、メモリが少ない)であり、並列化可能であり、プレーンテキストブロックごとに1つのAES操作と1つのガロア乗算が必要であるという点で非常に優れています。ECBのようなクラシックモードは高速です(ブロックごとに1つのAES操作のみ)が、-繰り返しになりますが-整合性ロジックも考慮する必要があり、GMACよりも遅くなる可能性があります。

そうは言っても、GCMセキュリティはIVの作成に適切な乱数生成に依存していることに注意する必要があります。

于 2012-11-16T18:26:36.613 に答える