java web 安全,如何认证客户端?时间戳和noce如何抵御重放攻击?

发布于:2025-03-19 ⋅ 阅读:(17) ⋅ 点赞:(0)

技术问答整理

1. Java HMAC签名验签示例

问题

如何用Java实现HMAC签名和验签?

答案

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.HexFormat;

public class HmacExample {
    // 生成HMAC签名(HmacSHA256 + Hex编码)
    public static String generateHmac(String message, String key) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        mac.init(secretKey);
        byte[] hmacBytes = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
        return HexFormat.of().formatHex(hmacBytes);
    }

    // 验证HMAC签名
    public static boolean verifyHmac(String message, String key, String receivedSignature) throws Exception {
        return generateHmac(message, key).equals(receivedSignature);
    }
}

关键点

  • 算法选择:HmacSHA256/HmacSHA512
  • 编码统一:UTF-8处理字符串
  • 密钥安全:避免硬编码,使用密钥生成器
// 安全密钥生成示例
KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");
keyGen.init(256); // 256位密钥
byte[] key = keyGen.generateKey().getEncoded();

2. HMAC算法描述

问题

HMAC算法如何工作?有哪些核心特性?

答案

定义
HMAC(Hash-based Message Authentication Code)是基于哈希函数的消息认证码,用于验证数据完整性和真实性。

公式
[ \text{HMAC}(K, M) = H\left( (K \oplus \text{opad}) \parallel H\left( (K \oplus \text{ipad}) \parallel M \right) \right) ]

特性

  • 抗碰撞性:依赖哈希函数(如SHA-256)
  • 密钥依赖:安全性要求密钥保密
  • 应用场景:API签名、JWT令牌、文件校验

哈希算法对比

算法 输出长度 安全性建议
HmacSHA256 256位 ✅ 推荐使用
HmacSHA512 512位 ✅ 高安全场景
HmacSHA1 160位 ⚠️ 仅兼容旧系统

3. 重放攻击防御

问题

如何通过时间戳和Nonce防御重放攻击?

答案

防御机制

  1. 时间戳

    • 客户端在请求中添加当前时间戳
    • 服务端校验时间窗口(如±5分钟)
    long timestamp = System.currentTimeMillis() / 1000;
    if (Math.abs(currentTime - timestamp) > 300) { /* 拒绝请求 */ }
    
  2. Nonce(一次性随机数)

    • 客户端生成唯一Nonce(如UUID)
    • 服务端缓存已用Nonce,拒绝重复值
    String nonce = UUID.randomUUID().toString();
    if (redisCache.exists(nonce)) { /* 拒绝请求 */ }
    

联合防御

  • 时间戳解决历史请求重放
  • Nonce解决即时重放
  • 两者需参与HMAC签名计算

4. 挑战-响应机制

问题

挑战-响应机制如何实现身份验证?

答案

核心流程

  1. 客户端发起认证请求
  2. 服务端返回随机挑战值(Challenge)
  3. 客户端用密钥生成响应(Response)
  4. 服务端验证响应合法性

实现方式

  • 对称加密(HMAC)
    // 响应生成:HMAC(Challenge, SecretKey)
    String response = HmacExample.generateHmac(challenge, key);
    
  • 非对称加密(数字签名)
    // 客户端用私钥签名
    Signature sig = Signature.getInstance("SHA256withRSA");
    sig.initSign(privateKey);
    byte[] signature = sig.sign();
    

应用场景

  • OAuth 2.0 PKCE:code_verifiercode_challenge
  • SSH登录:服务器发送加密挑战,客户端用私钥解密


网站公告

今日签到

点亮在社区的每一天
去签到