跳到主要内容
ecdsa.com
firebase/php-jwt 7.x (PHP)PHP

错误信息

Provided key is too short

也可能输出为

  • DomainException: Provided key is too short

`JWT::encode` 和 `JWT::decode` 都会抛出这个错误。php-jwt 6.x 及更早版本接受过短的密钥,因此这个错误通常在升级到 7.x 之后立即出现。

firebase/php-jwt 7.x (PHP) — DomainException from JWT::encode / JWT::decode

含义

php-jwt 7 在签名或验证之前会检查密钥长度:HMAC 密钥的位数至少要等于哈希的位数(HS256 为 32 字节,HS384 为 48 字节,HS512 为 64 字节),RSA 密钥至少 2048 位,EC 密钥至少要达到其算法所要求的长度。更短的密钥会被拒绝,因为用它保护的令牌可以被伪造——过短的 HMAC 密钥经不起离线暴力破解,1024 位 RSA 则低于当前的最低要求。

原因

修复方法

  1. 1.

    生成新的随机密钥

    使用 `random_bytes` 或 `openssl rand` 生成,并把密钥保存在机密存储中。轮换密钥会使现有令牌失效,因此如有需要,应安排一段较短的新旧密钥并存期。

    bash
    # HS256 needs >= 32 bytes, HS512 >= 64; generate and store as base64
    php -r 'echo base64_encode(random_bytes(64)), PHP_EOL;'
  2. 2.

    以 base64 编码存储,使用解码后的字节

    在启动时校验一次长度,这样弱密钥会在部署阶段就失败,而不是等到第一个请求时才失败。

    php
    $secret = base64_decode(getenv('JWT_SECRET_B64'), true);
    if ($secret === false || strlen($secret) < 32) {
        throw new RuntimeException('JWT_SECRET_B64 must decode to at least 32 bytes');
    }
    $token = JWT::encode($claims, $secret, 'HS256');
    $decoded = JWT::decode($token, new Key($secret, 'HS256'));
  3. 3.

    替换过短的 RSA 密钥

    生成 2048 位或更长的 RSA 密钥——或者改用 ES256 和 P-256 密钥——先发布新的公钥,再用新密钥签名。

    bash
    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out rs256-private.pem

相关错误

浏览完整的签名错误库