在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
你是否出现了以下情况除外:
NoSuchPaddingException, NoSuchAlgorithmException
InvalidAlgorithmParameterException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException
现在,所有的这些都是GeneralSecurityException
的,所以它会很容易,赶上他们。 但看使用情况下,你可能不希望这样做。
如果你看一下例外的原因,那么你会发现,这些例外的 - 除了最后两个 - 生成算法或密钥的实现时才被抛出。 我认为这是合理的,一旦你测试你的应用程序,这些数值仍然或多或少是静态的。 因此,它是合乎逻辑的抛出-例如-一个IllegalStateException
。 IllegalStateException
是你是不是扔或挂钩需要一个运行时异常。 当然,你应该指出的安全异常为异常的原因 。
现在最后两个例外, BadPaddingException
和IllegalBlockSizeException
是不同的。 他们依赖于实际的密文,因此他们依赖于算法的输入。 现在,通常你应该始终验证输入的完整性你给它之前到您的Cipher
通过验证第一HMAC一个校验例如,对于解密发起的,例如)。 所以在这个意义上,你仍然可以逃脱运行时异常。
如果不检查其完整性,你应该做一些不同之处不同,比如重新抛出它作为一个(有什么不同?)检查异常。 如果拿这条路线,你应当理解有关填充神谕攻击; 如果对手可以尝试和解密的密文多次,并且发现如果填充正确与否则消息的保密性丢失。
这可能是最好使用单独try
/ catch
块的建设和初始化Cipher
和解密本身。 你也可以捕捉到的异常BadPaddingException
和IllegalBlockSizeException
处理之前GeneralSecurityException
。 与Java 7开始,您可以使用多catch语句以及(如catch(final BadPaddingException | IllegalBlockSizeException e)
最后一些注意事项:
- 要注意的是,如果未安装无限的加密文件(检查的异常可能会引发对AES密钥长度192位和256位甲骨文JavaSE的网站获取更多信息); 你应该检查是否在应用程序启动,则将允许密钥大小;
- 既
BadPaddingException
和IllegalBlockSizeException
可能由于攻击或由于数据没有完全本创建; -
BadPaddingException
也可如果密钥是不正确抛出。
如果你愿意损失一些specificty,所有的加密例外延长GeneralSecurityException ,你可以赶上来代替。
处理,最好的方式是创建一个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 )