处理加密例外(Handling crypto exceptions)

2019-08-18 06:21发布

在Java中处理加密\解密时,这很基本的,这段代码是很常见的。

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

这三条线单独,可能丢了6种异常,我不知道什么是干净的(以代码的可读性方面)的方式来处理它们。 六个catch子句在try真的看起来像一闻到我。

是否有微图案或最佳实践,我明显缺失的,这样的对象时?

编辑

对不起,我想我没有解释自己很好。 我的问题是不是真正的避免尝试\ catch子句,但如果有处理类似情况的常用方法。

唯一的例外是

NoSuchPaddingException, NoSuchAlgorithmException
InvalidAlgorithmParameterException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException

Answer 1:

你是否出现了以下情况除外:

NoSuchPaddingException, NoSuchAlgorithmException
InvalidAlgorithmParameterException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException

现在,所有的这些都是GeneralSecurityException的,所以它会很容易,赶上他们。 但看使用情况下,你可能不希望这样做。

如果你看一下例外的原因,那么你会发现,这些例外的 - 除了最后两个 - 生成算法或密钥的实现时才被抛出。 我认为这是合理的,一旦你测试你的应用程序,这些数值仍然或多或少是静态的。 因此,它是合乎逻辑的抛出-例如-一个IllegalStateExceptionIllegalStateException是你是不是扔或挂钩需要一个运行时异常。 当然,你应该指出的安全异常为异常的原因

现在最后两个例外, BadPaddingExceptionIllegalBlockSizeException是不同的。 他们依赖于实际的密文,因此他们依赖于算法的输入。 现在,通常你应该始终验证输入的完整性你给它之前到您的Cipher通过验证第一HMAC一个校验例如,对于解密发起的,例如)。 所以在这个意义上,你仍然可以逃脱运行时异常。

如果不检查其完整性,你应该做一些不同之处不同,比如重新抛出它作为一个(有什么不同?)检查异常。 如果拿这条路线,你应当理解有关填充神谕攻击; 如果对手可以尝试和解密的密文多次,并且发现如果填充正确与否则消息的保密性丢失。

这可能是最好使用单独try / catch块的建设和初始化Cipher和解密本身。 你也可以捕捉到的异常BadPaddingExceptionIllegalBlockSizeException处理之前GeneralSecurityException 。 与Java 7开始,您可以使用多catch语句以及(如catch(final BadPaddingException | IllegalBlockSizeException e)


最后一些注意事项:

  • 要注意的是,如果未安装无限的加密文件(检查的异常可能会引发对AES密钥长度192位和256位甲骨文JavaSE的网站获取更多信息); 你应该检查是否在应用程序启动,则将允许密钥大小;
  • BadPaddingExceptionIllegalBlockSizeException可能由于攻击或由于数据没有完全本创建;
  • BadPaddingException也可如果密钥是不正确抛出。


Answer 2:

如果你愿意损失一些specificty,所有的加密例外延长GeneralSecurityException ,你可以赶上来代替。



Answer 3:

处理,最好的方式是创建一个bussines异常(MyModuleException或东西),然后再次抛出该异常增加加密异常导致一部分。 这样一来你的方法会抛出只有一个例外,不是6,什么是更容易管理你的应用程序的其他层。

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 )



文章来源: Handling crypto exceptions