我有一些解密代码,期望Cipher.doFinal()在使用不正确的密钥/ iv时抛出异常。这似乎没有发生。嗯,确实发生了,但并非总是如此。
我的加密使用当前时间的“秒”作为Random()类的种子。然后,它使用模数为256的16(伪)随机值来生成16字节密钥。它使用此密钥加密。它对IV使用相同的字节数组。我正在按如下方式初始化密码:
Cipher.getInstance("AES/CBC/ISO10126Padding");
解密使用相同的逻辑循环所有可能的60秒值(0 - 59)以生成密钥和IV。对于每个密钥和IV,它尝试解密加密值。我经常会抛出一些BadPaddingException,但大部分时间它都会成功获得一个不正确的“秒”值。正如所料,我得到了垃圾回收。我期待doFinal()在使用错误的键/ iv时总是抛出异常。有什么理由不这样做吗?
举个例子:
如果加密时当前秒为45,则使用该值生成密钥/ iv。当我尝试解密时,我坐在从0到59的for循环中尝试每个值,直到doFinal()成功(例如,不会抛出异常)。我通常会看到一些BadPaddingException,但是循环将在45之前结束并且我会返回垃圾。
我确实找到了这个:
Java AES decryption detect incorrect key
这似乎有关系,虽然我没有使用密码流。
答案 0 :(得分:3)
解密本身无法检测到错误的密钥,结果只是垃圾。这是一种常见的误解,它将加密与身份验证混为一谈。
这就是为什么婴儿床被用来强制破解加密,所以人们可以从不正确的加密中判断正确,看看Bletchley Park如何打破德国加密并需要婴儿床。婴儿床是确定解密可能正确/不正确的某种方式。
有时如果使用填充,则填充将出错,而某些实现将返回错误。这实际上是一种安全违规,它通过填充泄漏信息。这是一种婴儿床。
如果要验证加密,则需要提供其他一些方法,例如添加要验证的数据哈希值。