0

与 DESfire EV1 标签交互时,AES-CBC 用于保护通信。加密并发送消息后,需要使用加密产生的 IV 对响应进行解密:

Cipher c = Cipher.getInstance("AES/CBC/NoPadding");
c.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(zeroBytes));

byte[] encrypted_response = transceive(c.doFinal(message));

// TODO: cipher needs to be re-set to DECRYPT_MODE while retaining the IV
c.init(Cipher.DECRYPT_MODE, ...?);

byte[] response = c.doFinal(encrypted_response);

不幸的是,Cipher.getIV() 返回初始 IV(全为零),似乎没有办法让 IV 缺少手动实现整个 CBC 部分。在加密字节后从密码获取更新的 IV中提出了一个类似的问题,但是只提供了特定于 CTR 的解决方案,这些解决方案不适用于 CBC 模式。

4

2 回答 2

2

您在此处将 encrypt IV 设置为全零:

new IvParameterSpec(zeroBytes)

因此,如果您使用随机字节,然后将这些随机字节作为您的 iv,请自己跟踪它们。

更新

从您的评论看来,您可能正在尝试重新开始解密中游或中块,使用 CBC 模式,您可以使用前一个密文块作为您的 IV,只要您在流或块中块对齐。

于 2013-03-25T13:25:17.817 回答
0

您可以Cipher通过调用从对象中获取 IV c.getIV(),这将返回一个包含 IV 数据的字节数组。然后,您可以将其插入解密端的 IVParametersSpec

也就是说,您init错误地使用了 Cipher 的方法。如果您在调用中提供 IVParameterSpec,它将不会生成内部 IV(正如您在对另一个答案的评论中所说)init。相反,它将使用全零的 IV,因为这就是该版本 init告诉它要做的事情。相反,使用 init 调用,c.init(Cipher.ENCRYPT_MODE, secretKey)然后使用上面c.getIV()的方法将 IV 取出。在此处查看Cipher 的 javadocs以了解我的意思。

于 2013-03-25T19:00:47.250 回答