Java 加密及;使用OutputStream/InputStream的HMAC(基于流的加密,然后是MAC)

Java 加密及;使用OutputStream/InputStream的HMAC(基于流的加密,然后是MAC),java,encryption,cryptography,cryptoapi,Java,Encryption,Cryptography,Cryptoapi,我正在寻找一种简单的方法,使用InputStream/OutputStreams通过Java中的密文计算HMAC(然后加密MAC,包括IV和算法参数) 尝试失败:我第一次尝试从CipherOutputStream继承,但他们不允许在编写密文后通过编程检索密文——这让我得出结论,只有使用CipherOutputStream才能实现加密。代码如下: 成功的尝试:然后我使用CipherOutputStream的OpenJDK7源代码作为实现CipherHmacOutputStream类的基础,该类在

我正在寻找一种简单的方法,使用InputStream/OutputStreams通过Java中的密文计算HMAC(然后加密MAC,包括IV和算法参数)

  • 尝试失败:我第一次尝试从CipherOutputStream继承,但他们不允许在编写密文后通过编程检索密文——这让我得出结论,只有使用CipherOutputStream才能实现加密。代码如下:

  • 成功的尝试:然后我使用CipherOutputStream的OpenJDK7源代码作为实现CipherHmacOutputStream类的基础,该类在调用write()时更新Hmac(mac.update()),并在调用close时将其追加到流中。代码如下:

现在的问题是,当我尝试编写匹配的CipherHmacInputStream时,没有明显的方法来判断HMAC何时开始,因为无法判断流何时结束。available()方法只返回缓冲区中的“新”解密字节。因此,解密(cipher.update())可能会错误地尝试解密HMAC。我已经在这方面投入了一些时间,但是必须有一种更简单的方法来使用HMACs进行基于流的加密/解密。GCM/EAX是显而易见的答案,但我想让算法/模式保持可配置状态,如果不使用GCM/EAX,还可以提供消息身份验证


你有什么想法吗?有什么标准方法可以做到这一点吗?

您正在将两段数据烘焙成一种序列化形式。您必须使用某种类型的标题来存储长度,以便以后可以隔离每个标题。在编写过程中,向数据报添加一个版本,以便将来可以保持向后兼容性。

问题是,虽然带有长度字段的标头非常有用,但直到写入最后一个字节,密文的长度才知道。HTTP使用块来处理此问题。为每个数据块编写一个单字节头。如果大小为零,则表示您已到达终点,例如,关于第一个“失败”解决方案的0xff 0x10 0x00。您可以在
CipherOutputStream
OutputStream
之间添加
FilterOutputStream
,以捕获密文。