【问题标题】:Encryption & HMAC using OutputStream/InputStream (stream-based encrypt-then-MAC)使用 OutputStream/InputStream 的加密和 HMAC(基于流的 encrypt-then-MAC)
【发布时间】:2013-09-13 22:14:21
【问题描述】:

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

  • 尝试失败:我首先尝试从 CipherOutputStream 继承,但在密文编写完成后,他们不允许以编程方式检索密文 - 导致我得出结论,仅使用 CipherOutputStream 可以实现 MAC-then-encrypt .此处代码:http://pastebin.com/armvDN3N

  • 成功尝试:然后我使用 CipherOutputStream 的 OpenJDK7 源代码作为实现 CipherHmacOutputStream 类的基础,该类在调用 write() 时更新 Hmac (mac.update()) 并将其附加到流当 close 被调用时。代码在这里:http://pastebin.com/fF8WFBpA

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

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

【问题讨论】:

  • 关于您的第一个“失败”解决方案。您可以在CipherOutputStreamOutputStream 之间添加您的FilterOutputStream 来捕获密文。

标签: java encryption cryptography cryptoapi


【解决方案1】:

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

【讨论】:

  • 问题在于,虽然带有长度字段的标头非常有用,但在写入最后一个字节之前,密文的长度是未知的。
  • HTTP 用块来处理这个问题。为每个数据块写入一个字节的标头。如果大小为零,则意味着您已经到达终点,例如0xff 0x10 0x00
猜你喜欢
  • 2018-04-07
  • 1970-01-01
  • 1970-01-01
  • 2018-02-25
  • 2012-08-03
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多