php-jwt 基于 openssl 扩展和 libsodium,用 JWT::encode() 和 JWT::decode() 编码和解码令牌。从第 6 版起,Key 对象——即密钥材料加算法——成为必需,因此算法来自你的代码,而不是来自令牌:一个 RS256 令牌和一个用 EC 密钥的 PEM 文本伪造的 HS256 令牌,用 new Key($pem, 'ES256') 验证时都报错 Incorrect key for this algorithm;未签名的令牌则报错 Algorithm not supported。这层防护只在由应用构造 Key 时才成立;new Key($pem, 'HS256') 就让伪造的令牌验证通过了。
7.2.1 版支持 HS256/384/512、RS256/384/512、ES256、ES384、ES256K 和 EdDSA。不支持 ES512(Algorithm not supported),PS256 需要安装 phpseclib/phpseclib,PS384 和 PS512 则完全不可用——颁发者使用这些算法时,其令牌需要用 web-token 或 lcobucci/jwt 处理。短于哈希长度的 HMAC 密钥会被拒绝(Provided key is too short)。
ES256 没有与 P-256 绑定:头部为 ES256、却用 P-384 密钥签名的令牌,由该库自己生成,也被它自己接受,尽管其他库会拒绝。ES256 签名会被转换为 JWS 要求的 64 字节原始 r‖s;DER 签名会报错 Signature verification failed。可以在 JWT 调试器中检查令牌的签名。
声明的处理非常简单。exp、nbf 和 iat 只在存在时才检查,JWT::$leeway 是默认为 0 的全局静态变量,而且完全不校验颁发者和受众——示例自行检查 exp 和 iss。基于 JWKS 验证时,JWK::parseKeySet() 把密钥集转换为 Key 对象;可以用 JWKS 检测查看提供方发布的密钥集。