处理Java加密异常 [英] Handling Java crypto exceptions

查看:345
本文介绍了处理Java加密异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This, pretty basic, piece of code is quite common when handling encryption / decryption in Java.

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

仅这三行可能会引发六个异常,我不确定最干净的是代码可读性)来处理它们。
尝试使用六个catch子句对我来说真的像是一种气味。

These three lines alone, potentially throw six exceptions and I'm not sure what's the cleanest (in terms of code readability) way to handle them. A try with six catch clauses really looks like a smell to me.

在使用此类对象时,是否存在微模式或最佳实践,我显然不见了?

Are there micropatterns or best practices, I am obviously missing, when working with such objects?

编辑

对不起,我想我对自己的解释不是很清楚好。我的问题不是真的要避免使用try\catch子句,而是要有一种通用的方式来处理类似情况。

Sorry, I think I didn't explain myself very well. My question is not really about avoiding a try\catch clause, but if there is a common way to handle similar situations.

加密例外是

NoSuchPaddingException, NoSuchAlgorithmException
InvalidAlgorithmParameterException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException


推荐答案

您指出了以下例外情况:

You indicated the following exceptions:

NoSuchPaddingException, NoSuchAlgorithmException
InvalidAlgorithmParameterException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException

现在所有这些都是 GeneralSecurityException ,因此很容易将它们全部捕获。但是查看用例,您可能不想这样做。

Now all of these are GeneralSecurityException's, so it would be easy to catch them all. But looking at the use case, you probably don't want to do that.

如果您查看原因,然后,您将发现这些异常中的任何一个(最后两个除外)仅在生成算法或密钥的实现时抛出。我认为在测试了应用程序之后,这些值或多或少保持静态是合理的。因此,抛出一个 IllegalStateException IllegalStateException 是运行时异常,不需要抛出(在方法签名中)或捕获。当然,您应将安全性例外作为例外的原因[em]。

If you look at the cause of the exceptions then you will find that any of these exceptions - except for the last two - are only thrown when generating an implementation of an algorithm or a key. I think it is reasonable that once you have tested your application that these values remain more or less static. Hence it would be logical to throw - for instance - an IllegalStateException. IllegalStateException is a runtime exception which you are not required to throw (in the method signature) or catch. Of course, you should include the security exception as being the cause of the exception.

现在,最后两个例外 BadPaddingException IllegalBlockSizeException 是不同的。它们取决于实际的密文,因此取决于算法的输入。现在,通常,您应该始终先验证输入的完整性,然后再将其输入到 Cipher 实例,例如通过首先验证HMAC校验和而发起解密。因此从这种意义上讲,您仍然可以摆脱运行时异常。如果不对完整性进行单独检查,则不应将其转换为 RuntimeException 。相反,您可以让用户处理该异常,也可以将其作为用例特定的异常重新抛出。

Now the last two exceptions, BadPaddingException and IllegalBlockSizeException are different. They depend on the actual ciphertext, so they are dependent on the input of the algorithm. Now normally you should always verify the integrity of the input before you feed it into your Cipher instance, initiated for decryption, for instance by first validating a HMAC checksum). So in that sense you could still get away with a runtime exception. If you don't perform a separate check for integrity then you should do should not convert to a RuntimeException. Instead you could either let the user handle the exception, or re-throw it as a use case specific exception.

如果您处理 BadPaddingException 通过(重新)抛出它,然后应该了解明文oracle攻击,例如padding oracle攻击。对于CBC模式下的填充oracle攻击:如果攻击者可以尝试让您多次解密密文,并且收到解密成功(或失败)的提示,那么他们可以获取消息的明文而不会破坏密文。因此,在可以处理身份验证标签的其他16个字节的情况下,最好使用诸如GCM模式之类的经过身份验证的模式。

If you handle the BadPaddingException by (re-)throwing it then should understand about plaintext oracle attacks such as padding oracle attacks. For padding oracle attacks in CBC mode: if an adversary can try and let you decrypt ciphertext multiple times and receive an indication that decryption failed (or not) then they can retrieve the plaintext of the message without breaking the cipher. For this reason an authenticated mode such as GCM mode should be preferred in situations that can handle the 16 additional bytes for the authentication tag.

最好使用单独的 try / catch 块来构造和初始化 Cipher 和解密本身。在处理 BadPaddingException 和 IllegalBlockSizeException 的异常。 .com / javase / 6 / docs / api / java / security / GeneralSecurityException.html rel = nofollow noreferrer> GeneralSecurityException 。从Java 7开始,您也可以使用多捕获语句(例如 catch(final BadPaddingException | IllegalBlockSizeException e))。

It is probably best to use separate try/catch blocks for the construction and initialization of the Cipher and the decryption itself. You could also catch the exceptions BadPaddingException and IllegalBlockSizeException before handling the GeneralSecurityException. Starting with Java 7 you may use multi-catch statements as well (e.g. catch(final BadPaddingException | IllegalBlockSizeException e)).

最后一些注意事项:


  • BadPaddingException IllegalBlockSizeException 可能会被 Cipher 抛出,因为未完全接收到数据,或者是因为攻击者弄乱了数据;

  • BadPaddingException

  • 请注意,可能会为192位和256位的AES密钥引发异常。没有安装无限的加密文件(请检查 Oracle JavaSE网站有关更多信息);您应该检查启动应用程序时是否允许密钥大小(主要适用于Java旧版本/不推荐使用的版本);

  • BadPaddingException and IllegalBlockSizeException may be thrown by Cipher because of because the data was not completely received, or because of an attacker messing with the data;
  • BadPaddingException may also be thrown if the key is incorrect.
  • Beware that an exception may be thrown for AES key sizes 192 bit and 256 bit if the unlimited crypto files are not being installed (check the Oracle JavaSE site for more info); you should check if the key size is permitted when the application is started (this is mainly true for old / deprecated versions of Java);

这篇关于处理Java加密异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆