Loading... # 核心设计思路 安全认证方案主要解决以下几个核心问题: * **防重放攻击**:通过时间戳和随机 Nonce 值限制请求的有效期 * **防请求篡改**:通过 HMAC 签名验证请求参数的完整性 * **防时序攻击**:使用安全的字符串比较方式验证令牌 * **密钥安全**:通过密钥派生函数 (KDF) 增强原始密钥的安全性 # 核心代码实现与解析 ## 数据结构定义 首先定义存储令牌信息的`AuthToken`类,包含时间戳、随机数和签名令牌三个核心字段: ```java public static class AuthToken { private final long timestamp; // 时间戳(秒级) private final String nonce; // 随机数 private final String token; // 签名令牌 public AuthToken(long timestamp, String nonce, String token) { this.timestamp = timestamp; this.nonce = nonce; this.token = token; } // Getter方法... } ``` ## 核心配置参数 定义认证方案的核心配置,可根据业务需求调整: ```java // 令牌有效期(5分钟) private static final long TIME_WINDOW_SECONDS = TimeUnit.MINUTES.toSeconds(5); // 加密算法 private static final String HMAC_ALGORITHM = "HmacSHA256"; // HKDF盐值和信息字段(增强密钥派生安全性) private static final String HKDF_SALT = "HKDF_SALT"; private static final String HKDF_INFO = "HKDF_INFO"; // 随机数长度(16字节) private static final int NONCE_LENGTH = 16; ``` ## 令牌生成逻辑 `generateToken`方法是整个认证方案的核心,负责生成包含时间戳、随机数和签名的完整令牌: ```java public static AuthToken generateToken(String clientId) { // 1. 获取当前秒级时间戳 long timestamp = Instant.now().getEpochSecond(); // 2. 生成随机Nonce值(防止重放攻击) String nonce = generateNonce(); // 3. 构建签名原文:时间戳_随机数_客户端ID String message = String.join("_", String.valueOf(timestamp), nonce, clientId != null ? clientId : "" ); // 4. 密钥派生:通过双重HMAC增强密钥安全性 byte[] derivedKey = deriveKey((clientId != null ? clientId : "").getBytes(StandardCharsets.UTF_8)); // 5. 计算HMAC-SHA256签名 String token = hmacDigest(derivedKey, message); return new AuthToken(timestamp, nonce, token); } ``` ## 密钥派生函数 为了提升密钥安全性,我们实现了基于 HKDF 思想的密钥派生函数,通过双重 HMAC 处理原始密钥: ```java private static byte[] deriveKey(byte[] inputKey) { try { // 第一轮HMAC:使用盐值处理原始密钥 Mac hmac1 = Mac.getInstance(HMAC_ALGORITHM); SecretKeySpec keySpec1 = new SecretKeySpec(HKDF_SALT.getBytes(StandardCharsets.UTF_8), HMAC_ALGORITHM); hmac1.init(keySpec1); byte[] tempKey = hmac1.doFinal(inputKey); // 第二轮HMAC:使用临时密钥处理信息字段 Mac hmac2 = Mac.getInstance(HMAC_ALGORITHM); SecretKeySpec keySpec2 = new SecretKeySpec(tempKey, HMAC_ALGORITHM); hmac2.init(keySpec2); return hmac2.doFinal(HKDF_INFO.getBytes(StandardCharsets.UTF_8)); } catch (NoSuchAlgorithmException | InvalidKeyException e) { throw new RuntimeException("Failed to derive key", e); } } ``` ## 令牌验证逻辑 验证过程是生成过程的逆操作,重点包含时间窗口校验和安全的令牌比较: ```java public static boolean verifyToken(long timestamp, String nonce, String clientId, String receivedToken) { // 1. 时间窗口校验:超出5分钟直接拒绝 long currentTime = Instant.now().getEpochSecond(); if (Math.abs(currentTime - timestamp) > TIME_WINDOW_SECONDS) { return false; } // 2. 重新生成令牌 String message = String.join("_", String.valueOf(timestamp), nonce, clientId != null ? clientId : "" ); byte[] derivedKey = deriveKey((clientId != null ? clientId : "").getBytes(StandardCharsets.UTF_8)); String expectedToken = hmacDigest(derivedKey, message); // 3. 安全比较:防止时序攻击 return secureCompare(expectedToken, receivedToken); } ``` ## 安全比较方法 普通的字符串 equals 方法存在时序攻击风险,我们实现了恒定时间的比较方法: ```java private static boolean secureCompare(String a, String b) { if (a == null || b == null) { return false; } if (a.length() != b.length()) { return false; } int result = 0; // 遍历所有字符,确保比较时间恒定 for (int i = 0; i < a.length(); i++) { result |= a.charAt(i) ^ b.charAt(i); } return result == 0; } ``` ## 请求头集成 在实际的 HTTP 请求中,我们需要将生成的令牌信息添加到请求头中: ```java // 执行在发送请求前 req.addHeader("timestamp", authToken.getTimestamp()); // 添加时间戳 req.addHeader("nonce", authToken.getNonce()); // 添加随机数 req.addHeader("clientId", deviceSerial); // 添加客户端ID req.addHeader("token", authToken.getToken()); // 添加签名令牌 ``` # 完整使用示例 ```java public static void main(String[] args) { // 1. 生成令牌(传入客户端唯一标识) AuthToken authToken = generateToken("2b0ad3b668d44fa4"); // 2. 模拟验证令牌 boolean isValid = verifyToken( authToken.getTimestamp(), authToken.getNonce(), "2b0ad3b668d44fa4", authToken.getToken() ); System.out.println("令牌验证结果:" + isValid); // 输出 true } ``` # 总结 1. 该 API 安全认证方案基于 HMAC-SHA256 实现,核心通过**时间戳 + 随机 Nonce + 密钥派生 + 签名验证**四重机制保障接口安全 2. 方案重点解决了重放攻击、请求篡改和时序攻击三大安全问题,同时兼顾性能和易用性 3. 实际应用中需注意密钥的安全管理、HTTPS 传输和请求频率限制等配套安全措施,进一步提升整体安全性 最后修改:2026 年 03 月 17 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 5 如果觉得我的文章对你有用,请随意赞赏