概述

设想这样一种场景:两个实体需要进行通信,并且他们需要一种方法来验证接收到的消息未被篡改。基于哈希的消息认证码(Hash-based Message Authentication Code,HMAC)是一个很好的解决方案。

在这个教程中,我们将探讨如何在Java中使用HMAC算法。

2. 哈希消息认证码(HMAC)

HMAC是一种加密方法,确保了两个实体之间消息的完整性

HMAC算法由一个密钥和一个哈希函数组成。密钥是一个独特的信息或字符字符串,发送者和接收者都熟知。

哈希函数是一种将一个序列映射到另一个序列的算法。

下面的图展示了HMAC算法的高层次流程:

HMAC使用诸如MD5SHA-*等密码哈希函数。

3. 使用JDK API的HMAC

Java提供了一个内置的Mac来生成HMAC。 初始化Mac对象后,我们调用*doFinal()*方法执行HMAC操作。此方法返回一个包含HMAC结果的字节数组。

让我们定义一个方法,用于使用MD5、SHA-1、SHA-224、SHA-256、SHA-384和SHA-512等各种哈希算法计算HMAC:

// 示例代码
public byte[] calculateHMAC(String algorithm, String data, String key) {
    // ...
}

下面是一个示例测试,展示如何计算HMAC:

// 示例测试
@Test
public void hmacExample() {
    String data = "Simple string data";
    String key = "Secret key";
    String expectedHMAC = "Expected HMAC result";

    byte[] hmacResult = calculateHMAC("HmacSHA512", data, key);
    assertEquals(expectedHMAC, new String(hmacResult));
}

在这个测试中,我们使用了简单的字符串数据和密钥,以及HmacSHA512算法。然后,我们断言HMAC结果与预期数据相等。

4. Apache Commons库

Apache Commons库也提供了用于HMAC计算的实用类。

4.1. 添加Maven依赖

为了使用Apache Commons的实用类,我们需要在pom.xml中添加commons-codec依赖:

<!-- 示例代码 -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

4.2. HmacUtils

要计算HMAC,我们可以使用HmacUtils。初始化HmacUtils对象后,我们调用*hmacHex()*方法执行HMAC操作。这个方法返回一个包含HMAC结果的十六进制字符串。

创建一个生成HMAC的方法:

// 示例代码
public String generateHMAC(String algorithm, String data, String key) {
    // ...
}

编写一个示例测试:

// 示例测试
@Test
public void apacheCommonsHMACExample() {
    String data = "Simple string data";
    String key = "Secret key";
    String expectedHMAC = "Expected HMAC result";

    String hmacResult = generateHMAC("HmacMD5", data, key);
    assertEquals(expectedHMAC, hmacResult);
}

在这个测试中,我们使用了HmacMD5算法。

5. BouncyCastle库

同样地,**我们也可以使用BouncyCastle库**。BouncyCastle是一组可以在Java中使用的加密API集合。

5.1. 添加Maven依赖

在开始使用库之前,我们需要在pom.xml文件中添加bcpkix-jdk15to18依赖:

<!-- 示例代码 -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15to18</artifactId>
    <version>1.68</version>
</dependency>

5.2. Hmac

首先,根据所需的哈希算法实例化HMac。然后,使用*update()方法更新HMAC对象以处理输入数据。最后,调用doFinal()*方法生成HMAC代码:

// 示例代码
HMac hmac = Mac.getInstance(algorithm);
hmac.init(new SecretKeySpec(key.getBytes(), algorithm));
byte[] hmacCode = hmac.doFinal(data.getBytes());

以下是一个生成HMAC并验证其正确性的示例:

// 示例测试
@Test
public void bouncyCastleHMACExample() {
    String data = "Simple string data";
    String key = "Secret key";
    byte[] expectedHMAC = ...; // 获取预期的HMAC字节数组

    byte[] hmacResult = generateBouncyCastleHMAC("HmacSHA512", data, key);
    assertArrayEquals(expectedHMAC, hmacResult);
}

在这个测试中,我们使用了HmacSHA512算法。

6. 总结

HMAC提供了数据完整性检查功能。在这篇文章中,我们学习了如何使用Java中的HMAC算法为输入字符串数据生成HMAC。此外,我们讨论了在HMAC计算中使用Apache Commons和BouncyCastle库的方法。

如往常一样,本文的完整源代码可在GitHub上找到。