java - 混淆使用 AES 和 Hmac 的客户端和服务器如何相互验证

标签 java encryption aes hmac hmacsha1

场景是这样的:我有一个客户端和服务器在通话。这是标准的想法:

  • 使用 Diffie-Hellman 生成客户端和服务器之间的 key 。
  • 在客户端和服务器上将此 key 用于 AES/CTR/PKCS7Padding 密码。
  • 对原始邮件使用 Hmac
  • 使用 AES 密码加密 Hmac 消息

所以这将允许客户端和服务器安全地交谈。

我正在查看的相关代码示例是此处的教程:Tampered message with HMac, encryption with AES in CTR mode : Advanced Encryption Standard « Security « Java Tutorial

我能够为客户端和服务器生成 key 。我可以使用 Hmac 和 AES 对其进行加密。由于加密和解密是独立发生的,我不确定如何检索解密所需的相关信息。

这是我感到困惑的部分:

cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);

byte[] plainText = cipher.doFinal(cipherText, 0, ctLength);
int messageLength = plainText.length - hMac.getMacLength();

hMac.init(hMacKey);
hMac.update(plainText, 0, messageLength);

byte[] messageHash = new byte[hMac.getMacLength()];

如果客户端发送加密消息,服务器如何获取ivSpechMac.getMacLength()hMacKey?服务器需要这些项目才能解密来自客户端的消息。

我知道初始化 vector (IV) 可以从密文中保留下来,因为它被附加到生成的密文的开头(我想我必须手动添加它,因为我认为 AES 密码不会那样做?)。然而,用于验证消息完整性的 hMacKey 和 hMac 长度仍然是个谜。

最后一点,有人可以解释一下这一行的目的是什么吗?这是加密还是解密?

     cipherText[9] ^= '0' ^ '9';`

最佳答案

首先,对于这种事情,如果您真的要这样做,请使用 SSL。出于教育目的,这东西很酷。

正如其他人所说,这是一个证明HMAC在密文被篡改时起作用的例子。因此 cipherText[9] ^= '0' ^ '9';

为了使用 HMAC,您必须验证您使用密文获得的消息身份验证标签(由 hmac 返回的内容)是否与您应该拥有的标签相匹配。要在这段代码中执行此操作,您:1) 使用您协商的 key 解密消息,2) 使用您协商的不同 key 计算该文本的 hmac,然后 3) 比较两者是否相同。

因为您知道这些 key ,所以您可以解密消息并计算 mac。顺便说一下,mac 长度 b 是 hmac 函数的固定属性,并且是众所周知的。

因为您必须拥有生成有效标签的 key ,如果它们匹配,则消息是真实的。

请注意,此代码可能不安全,因为您需要对密文而非明文进行 MAC 处理。如果不这样做,您最终会遇到类似 Padding oracle attack 的问题。这破坏了一堆网站的安全 cookie 实现。对这类事情使用 SSL。

关于java - 混淆使用 AES 和 Hmac 的客户端和服务器如何相互验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9562366/

相关文章:

.net - 我什么时候会选择 AesCryptoServiceProvider 而不是 AesManaged 或 RijndaelManaged?

c++ - 字节与 XOR 相乘

c++ - 序列化公钥以通过网络发送

android - Laravel 中的 AES 256 CBC 加密和 android 中的解密

java - SonarQube 无法分析文件 : Java file

Java Servlet 和 GWT 服务在第一次请求时不共享 session

java - 实现 SSH 命令以返回 Apache Mina 中的文件内容

java - iText 5.5.3 由于字体大小的测量方式,ColumnText 无法正确换行文本

java - 字符串加密 PHP/Java

c - C 语言的简单凯撒密码程序