jose4j 基于 JDK 自带的提供程序实现 JWS、JWE、JWK 和 JWT:用 JsonWebSignature 签名,用 JwtConsumerBuilder 构建的 JwtConsumer 完成验证和声明检查。0.9.7 对 256/384/512 的 HS、RS、PS、ES 以及 EdDSA 完成了往返测试;ES256K、Ed25519 和 Ed448 不是它能识别的算法名称。
默认设置挡住了两种经典攻击,但没有限定算法。除非显式关闭签名要求,否则 none 会被拒绝('none' is a blocked algorithm.);密钥类型也必须匹配:用 EC 密钥验证 RS256 令牌,以及以 EC 密钥的 PEM 文本为密钥的 HS256 令牌,都验证失败(cannot be used for HMAC verification)。不过,密钥能执行的其他任何算法都会被接受,因此要像示例那样,用 setJwsAlgorithmConstraints(ConstraintType.PERMIT, ...) 锁定算法。用 PEM 字节构造的 HmacKey 让那个伪造的 HS256 令牌验证通过了——密钥必须来自配置,绝不能根据令牌自己声称的内容来确定。
密钥长度会被强制检查:ES256 拒绝 P-384 密钥(expects a key using P-256 but was P-384),HS256 拒绝了 16 字节的密钥,因为 RFC 7518 要求密钥长度至少与哈希输出相同。ES256 签名是 64 字节的原始 r‖s;DER 签名会报错 Invalid JWS Signature——JWT 调试器会显示签名长度。
声明检查的默认值一严一松:不留时钟偏差容差,比大多数团队预想的更严格;不要求 exp,则更宽松。凡是读取其他服务所发令牌的 JwtConsumer,都应调用 setRequireExpirationTime()、setExpectedIssuer()、setExpectedAudience() 和 setAllowedClockSkewInSeconds()。
对于加密令牌,JWE 查看器可以显示 jose4j 生成的 JWE 包含哪些内容。