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

时间:2012-03-05 06:09:22

标签: java encryption aes hmac hmacsha1

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

  • 使用Diffie-Hellman在客户端和服务器之间生成密钥。
  • 在客户端和服务器上使用此密钥进行AES / CTR / PKCS7Padding密码。
  • 在原始讯息中使用Hmac
  • 使用AES密码加密Hmac消息

因此,这将允许客户端和服务器安全地通话。

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

我能够为客户端和服务器生成密钥。我可以使用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?服务器上需要这些项来解密来自客户端的消息。

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

最后一点,有人可以解释一下这条线的用途是什么吗?这是加密还是解密?

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

1 个答案:

答案 0 :(得分:1)

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

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

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

由于您知道这些密钥,因此您可以解密消息并计算mac。 mac长度方式,是hmac函数的固定属性,并且是公知的。

因为您必须拥有生成有效标记的密钥,否则该消息是可信的。

作为一个注释,这段代码可能不安全,因为你需要MAC密文而不是明文。如果不这样做,最终会遇到诸如Padding oracle attack之类的问题,这些问题打破了一系列网站的安全cookie实施。使用SSL来做这些事情。