You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HmacSHA256生成JWT密钥仍报错:密钥字节数组为0位不安全

问题:生成HmacSHA256密钥后仍触发JWT密钥长度错误的原因

问题背景

我使用以下代码生成HmacSHA256密钥:

try {
    KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");
    keyGen.init(256);
    SecretKey secretKey = keyGen.generateKey();
    encodedSecretKey = Base64.getEncoder().encodeToString(secretKey.getEncoded());
    System.out.println("Generated secret key for JWT: " + encodedSecretKey);
} catch (NoSuchAlgorithmException e) {
    throw new RuntimeException("Failed to generate secret key for JWT", e);
}

但发起请求时收到如下错误提示:

message: "The specified key byte array is 0 bits which is not secure enough for any JWT HMAC-SHA algorithm. The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HMAC-SHA algorithms MUST have a size >= 256 bits (the key size must be greater than or equal to the hash output size). Consider using the Jwts.SIG.HS256.key() builder (or HS384.key() or HS512.key()) to create a key guaranteed to be secure enough for your preferred HMAC-SHA algorithm."

获取密钥的函数实现:

private SecretKey getKey() {
    byte[] keyBytes = Decoders.BASE64.decode(encodedSecretKey);
    return Keys.hmacShaKeyFor(keyBytes);
}

生成Token的代码:

public String generateAccessToken(UserDetails userDetails) {
    Map<String, Object> claims = new HashMap<>();
    List<String> roles = userDetails.getAuthorities().stream()
            .map(GrantedAuthority::getAuthority)
            .collect(Collectors.toList());
    claims.put("roles", roles);
    return Jwts.builder()
            .claims()
            .add(claims)
            .subject(userDetails.getUsername())
            .issuedAt(new Date(System.currentTimeMillis()))
            .expiration(new Date(System.currentTimeMillis() + 1000 * 60 * 30))
            .and()
            .signWith(getKey())
            .compact();
}

错误原因

核心问题是**encodedSecretKey变量在调用getKey()时未被正确初始化,为空值或空字符串**:

  • 当encodedSecretKey为空时,Base64解码后得到的字节数组长度为0,完全不符合HMAC-SHA256要求的至少256位密钥长度,因此触发错误。
  • 常见触发场景:
    • 密钥生成代码的执行时机晚于getKey()的调用(比如在生成Token之后才执行密钥生成逻辑);
    • encodedSecretKey作为类成员变量,在多实例环境中未被正确共享或赋值;
    • 密钥生成逻辑出现异常未被捕获,导致encodedSecretKey未被赋值。

验证与解决建议

  1. 验证问题:在getKey()方法中添加日志打印encodedSecretKey的值,确认其是否为空或未初始化;
  2. 解决方向:
    • 确保密钥生成逻辑在应用启动时提前执行,比如放到配置类的初始化方法中;
    • 将生成的密钥持久化到配置文件、环境变量或数据库,避免每次生成Token时才初始化;
    • 检查密钥生成代码的异常处理,确保encodedSecretKey在任何情况下都不会为空。

内容的提问来源于stack exchange,提问作者Shirish Jaiswal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:52:44