Skip to content

HMAC(Hash-based Message Authentication Code)是一种基于哈希函数的消息认证码算法。它结合了密钥和哈希函数,用于验证消息的完整性和真实性。

HMAC 算法的原理是将消息与一个密钥进行混合,并利用哈希函数对混合后的数据进行计算,生成一个固定长度的摘要。这个摘要可以用来验证消息是否被篡改过或伪造过。

HMAC 算法常用于网络通信中的身份验证、数字签名以及防止重放攻击等场景。在实际应用中,常见的哈希函数包括 MD5、SHA-1、SHA-256 等。

下面是一个使用 HmacMD5 算法计算消息摘要的简单示例代码:

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class HmacMD5Example {
    public static void main(String[] args) {
        String message = "Hello, world!";
        String key = "mySecretKey";

        try {
            // 创建 HmacMD5 实例
            Mac hmacMD5 = Mac.getInstance("HmacMD5");

            // 创建密钥对象
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacMD5");

            // 初始化 HmacMD5 实例
            hmacMD5.init(secretKey);

            // 计算消息摘要
            byte[] digest = hmacMD5.doFinal(message.getBytes());

            // 将摘要转换为十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : digest) {
                String hex = Integer.toHexString(0xFF & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }

            System.out.println("HMAC-MD5 摘要:" + hexString.toString());
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }
    }
}

在上述示例中,我们首先创建了一个 HmacMD5 的实例,并使用指定的密钥初始化它。然后,我们通过调用 doFinal 方法来计算消息的摘要值,并将其转换成十六进制字符串进行打印输出。

请注意,在实际应用中,为了安全起见,密钥应该是一个随机生成的、足够复杂的字符串,并且需要妥善保管。 Java标准库中的KeyGenerator类可以用于生成安全的随机密钥。这些密钥通常用于对称加密算法(如AES)或消息认证码算法(如HMAC)。

以下是一个使用KeyGenerator生成随机密钥的示例代码:

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;

public class KeyGeneratorExample {
    public static void main(String[] args) {
        try {
            // 创建KeyGenerator实例,指定算法为AES
            KeyGenerator keyGen = KeyGenerator.getInstance("AES");
            
            // 生成128位的随机密钥
            keyGen.init(128);
            
            // 生成密钥
            SecretKey secretKey = keyGen.generateKey();
            
            // 打印密钥的字节数组形式
            byte[] keyBytes = secretKey.getEncoded();
            System.out.println("Generated Key: " + bytesToHex(keyBytes));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    // 将字节数组转换为十六进制字符串表示
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }
}

上述示例代码使用AES算法生成了一个128位的随机密钥,并将其以十六进制字符串的形式打印出来。 请注意,在实际应用中,生成密钥时应根据具体需求选择合适的密钥长度,并采取适当的安全措施来保护生成的密钥。