java-jwt 用 JWT.create()…sign(algorithm) 构建令牌,用 JWT.require(algorithm)…build().verify(token) 验证令牌。Algorithm 对象同时携带算法和密钥,因此验证器只会接受这一种算法:RS256 令牌、未签名的令牌,以及用 EC 密钥的 PEM 文本伪造的 HS256 令牌,用 ES256 验证器验证时都报错 AlgorithmMismatchException。
这层防护只在 Algorithm 来自配置时才成立。JWT.require(Algorithm.none()) 会接受未签名的令牌,Algorithm.HMAC256(pemBytes) 也让伪造的 HS256 令牌验证通过了——如果代码根据令牌头部的 alg 选择 Algorithm,或把密钥加载为原始字节,就会重新引入这个 API 原本能防止的算法混淆缺陷。JWT.decode() 只解析,不检查签名,也不检查任何声明;它照样返回了一个一小时前就已过期的令牌。
支持的算法为 HMAC256/384/512、RSA256/384/512 和 ECDSA256/384/512——没有 PS256、ES256K 和 EdDSA——因此对于已改用 RSA-PSS 或 Ed25519 的颁发者,其令牌需要用 Nimbus 或 JJWT 处理。ES256 在签名时会拒绝 P-384 密钥。
ES256 签名是 64 字节的原始 r‖s,DER 签名会报出笼统的 The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA;JWT 调试器会显示签名长度。默认没有容差,exp 也是可选的:示例在检查颁发者的同时,加上了 withClaimPresence("exp") 和 acceptLeeway(30)。