跳到主要内容
ecdsa.com
ruby-jwt (Ruby)Ruby

错误信息

Signature verification failed (JWT::VerificationError)

也可能输出为

  • JWT::VerificationError: Signature verification failed

异常未被捕获时,Ruby 会先打印出错位置,后面跟着“Signature verification failed (JWT::VerificationError)”;这段文本在 ruby-jwt 2.10 和 3.3 中相同。

ruby-jwt (Ruby) — JWT::VerificationError from JWT.decode

含义

ruby-jwt 解码了令牌,并用你传入的密钥验证其签名,结果验证失败。令牌格式正确,算法也在允许之列;要么密钥不属于签名者,要么令牌被改动过。`JWT::VerificationError` 是 `JWT::DecodeError` 的子类,因此 `rescue JWT::DecodeError` 会把它和令牌格式错误一并捕获。

原因

修复方法

  1. 1.

    按 kid 从颁发者的 JWKS 中选择密钥

    `jwks:` 选项接受一个加载器;当令牌指定了未知的密钥时,ruby-jwt 会以 `kid_not_found: true` 再次调用它,因此能获取轮换后的新密钥。

    ruby
    require "jwt"
    require "net/http"
    
    jwks_loader = ->(options) do
      @jwks = nil if options[:kid_not_found] && @jwks_loaded_at.to_i < Time.now.to_i - 300 # refetch on rotation
      @jwks ||= begin
        @jwks_loaded_at = Time.now.to_i
        JSON.parse(Net::HTTP.get(URI("https://issuer.example.com/.well-known/jwks.json")))
      end
    end
    
    payload, header = JWT.decode(token, nil, true, algorithms: ["ES256"], jwks: jwks_loader,
                                 iss: "https://issuer.example.com/", verify_iss: true)
  2. 2.

    确认密钥确实匹配

    两边公钥部分的哈希相同,就可以排除密钥问题;接下来检查令牌是否在传输过程中被修改。

    bash
    openssl pkey -in issuer-private.pem -pubout | sha256sum
    openssl pkey -pubin -in configured-public.pem | sha256sum   # must be identical

相关错误

浏览完整的签名错误库