18

この非常に基本的なコードは、Java で暗号化/復号化を処理する場合に非常に一般的です。

final Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
cipher.doFinal(*something*);

これらの 3 行だけで 6 つの例外がスローされる可能性があり、それらを処理する最もクリーンな方法 (コードの読みやすさの観点から) はわかりません。6 つの catch 句を使用した try は、私には本当に匂いのように見えます。

そのようなオブジェクトを扱う場合、マイクロパターンやベスト プラクティスはありますか?

編集

申し訳ありませんが、私は自分自身をうまく説明できなかったと思います。私の質問は、try\catch 句を避けることではなく、同様の状況を処理する一般的な方法があるかどうかです。

暗号化の例外は次のとおりです。

NoSuchPaddingException, NoSuchAlgorithmException
InvalidAlgorithmParameterException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException
4

3 に答える 3

23

次の例外を指定しました:

NoSuchPaddingException, NoSuchAlgorithmException
InvalidAlgorithmParameterException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException

これらはすべて であるGeneralSecurityExceptionため、すべてをキャッチするのは簡単です。しかし、ユースケースを見ると、おそらくそれをしたくないでしょう。


例外の原因を見ると、これらの例外のいずれか (最後の 2 つを除く) は、アルゴリズムまたはキーの実装を生成するときにのみスローされることがわかります。アプリケーションをテストしたら、これらの値が多かれ少なかれ静的なままであることは妥当だと思います。したがって、たとえば、 an をスローすることは論理的IllegalStateExceptionです。IllegalStateException(メソッド シグネチャで) スローしたりキャッチしたりする必要のない実行時例外です。もちろん、例外の原因としてセキュリティ例外を含める必要があります。


最後の 2 つの例外は、BadPaddingExceptionIllegalBlockSizeExceptionが異なります。それらは実際の暗号文に依存するため、アルゴリズムの入力に依存します。通常、入力をCipherインスタンスにフィードする前に、入力の整合性を常に検証する必要があります。たとえば、最初に HMAC チェックサムを検証するなどして、復号化を開始します。その意味では、実行時例外を回避できます。整合性について個別のチェックを実行しない場合は、に変換しないでくださいRuntimeException。代わりに、ユーザーに例外を処理させるか、ユースケース固有の例外として再スローすることができます。

(再)スローして処理する場合は、BadPaddingExceptionオラクル攻撃のパディングなどのプレーンテキストのオラクル攻撃について理解する必要があります。CBC モードでのオラクル攻撃のパディングの場合: 敵対者が暗号文の復号化を複数回試みて、復号化が失敗した (または失敗した) という指示を受け取ることができる場合、暗号を破ることなくメッセージの平文を取得できます。このため、認証タグの追加の 16 バイトを処理できる状況では、GCM モードなどの認証モードを優先する必要があります。


の構築と初期化、および復号化自体には、別々のtry/catchブロックを使用するのがおそらく最善です。を処理する前に、例外をCipherキャッチすることもできます。Java 7 以降では、マルチキャッチ ステートメントも使用できます (例: )。BadPaddingExceptionIllegalBlockSizeExceptionGeneralSecurityExceptioncatch(final BadPaddingException | IllegalBlockSizeException e)


最後にいくつかの注意事項:

  • BadPaddingExceptionデータが完全に受信されていないか、攻撃者がデータをいじっているためにIllegalBlockSizeExceptionスローされる可能性があります。Cipher
  • BadPaddingExceptionキーが正しくない場合にもスローされる可能性があります。
  • 無制限の暗号ファイルがインストールされていない場合、AES キー サイズが 192 ビットおよび 256 ビットの場合に例外がスローされる可能性があることに注意してください (詳細については、Oracle JavaSE サイトを確認してください)。アプリケーションの起動時にキー サイズが許可されているかどうかを確認する必要があります (これは主に、Java の古いバージョンまたは廃止されたバージョンに当てはまります)。
于 2013-03-29T22:30:51.950 に答える
3

特定性を失いたくない場合は、Crypto のすべての例外がGeneralSecurityExceptionを拡張します。代わりにそれをキャッチできます。

于 2013-03-29T20:08:30.510 に答える
-3

これを処理する最善の方法は、ビジネス例外 (MyModuleException など) を作成し、Crypto 例外を追加してその例外を再スローして、一部を引き起こすことです。そうすれば、メソッドは例外を 6 つではなく 1 つだけスローするため、アプリケーションの他のレイヤーでの管理がはるかに簡単になります。

public void myMethod(...) throws MyModuleException {
  try {
    final Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key, iv);
    cipher.doFinal(*something*);
  } catch(Crypto1Ex ex){
    throw new MyModuleException("something is wrong", ex); //ex added, so it is not lost and visible in stacktraceses
  } catch(Crypto1Ex ex){
    throw new MyModuleException("something is wrong", ex);
  } //etc.
}

Java 7 では、さらに簡単に処理できます ( http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.htmlを参照) 。

于 2013-03-29T18:43:27.137 に答える