Java开发

使用 HMAC(Hash-based Message Authe

2025-07-03  本文已影响0人  _浅墨_

✅ HMAC 加密方式简介

HMAC 是一种基于哈希函数和密钥的消息认证码算法,常见如 HMAC-SHA256。它不是加密算法,而是用于生成一个固定长度的摘要,用来验证消息的完整性和真实性。

🔐 特点:


🧩 在登录流程中如何使用 HMAC?

你可以结合 HMAC 实现如下流程:

1. 客户端

// 假设用户输入明文 password = "myPassword"
String salt = generateRandomSalt(); // 客户端随机生成盐值或 nonce
String hmac = HmacUtils.hmacSha256(password, salt + serverPublicKey); // 使用服务端公钥作为密钥

发送:

{
  "username": "user",
  "password": "hmacResultHere", // HMAC 处理后的字符串
  "salt": "randomSaltValue"      // 或者用时间戳、nonce
}

2. 服务端

// 获取用户信息中的原始密码(已加密存储)
String storedPassword = user.getPassword(); 

// 使用相同逻辑计算预期 HMAC
String expectedHmac = HmacUtils.hmacSha256(storedPassword, salt + serverPublicKey);

if (expectedHmac.equals(receivedHmac)) {
    // 验证成功
}

🛡️ HMAC vs 加密(RSA/AES)

比较维度 HMAC RSA / AES(加密)
是否可逆 ❌ 不可逆 ✅ 可以解密
是否需要密钥 ✅ 需要共享密钥 ✅ 需要管理密钥
抗重放攻击 ❌ 需配合 nonce/salt 才能防御 ✅ 更好
数据完整性验证 ✅ 强项 ❌ 不提供
密码比对方式 必须服务端参与比对 可在客户端加密后直接比对数据库

✅ 推荐组合方案(更安全)

✅ HTTPS + 前端加密(RSA)+ 后端验证 + HMAC 防重放攻击

流程图:

前端:
明文密码 + nonce → HMAC → base64(encrypted by RSA public key)

后端:
接收密文 → RSA 解密 → 校验 HMAC → 查询数据库对比密码

示例代码片段(伪代码):

@PostMapping("/login")
public AjaxResult authLogin(@RequestBody LoginBody loginBody) {
    String decryptedPassword = RsaUtils.decrypt(loginBody.getPassword()); // 解密
    String receivedNonce = loginBody.getNonce();

    if (!HmacUtils.verify(decryptedPassword, receivedNonce, expectedKey)) {
        throw new CustomException("HMAC validation failed");
    }

    String token = loginService.authLogin(loginBody.getUsername(), decryptedPassword);
    return AjaxResult.success().put(Constants.TOKEN, token);
}

⚠️ 注意事项


✅ 总结

场景 是否适合 HMAC
纯粹验证身份 ✅ 可行,需配合 nonce/时间戳
密码传输 ⚠️ 可用,但建议结合加密(如 RSA)
安全性要求高 ❌ 单独 HMAC 不够,应搭配其他机制
防篡改 ✅ 推荐使用 HMAC

✅ 最佳实践建议:

如果你希望提升安全性且支持现代 Web 安全标准,推荐使用:

  • HTTPS + 前端 RSA 加密密码
  • 后端解密并使用 BCryptPasswordEncoder 对比数据库密码
  • 可选 HMAC 校验用于防篡改

这样既保证了传输安全,又提升了存储与验证的安全性。

上一篇 下一篇

猜你喜欢

热点阅读