本文へスキップ
ecdsa.com
jsonwebtoken (Rust crate)Rust

エラーメッセージ

Error(InvalidSignature)

別の表記

  • called `Result::unwrap()` on an `Err` value: Error(InvalidSignature)
  • InvalidSignature

`{:?}` は `Error(InvalidSignature)` を、`{}` は `InvalidSignature` を出力します。`.unwrap()` は「called `Result::unwrap()` on an `Err` value: Error(InvalidSignature)」でパニックします。

jsonwebtoken (Rust crate) — ErrorKind::InvalidSignature from decode()

このエラーの意味

`jsonwebtoken` クレートはトークンを解析してそのアルゴリズムを受け入れましたが、渡された `DecodingKey` では署名の検証に失敗しました。`Error(InvalidSignature)` はログや `unwrap()` のパニックで目にする `Debug` 形式で、`Display` 形式では単に `InvalidSignature` です。このクレートは「鍵の誤り」と「トークンの改変」を区別しません。どちらも、この鍵に対して署名が有効ではないことを意味します。

発生する理由

修正方法

  1. 1.

    エラーの種類を明示的に処理する

    `ErrorKind::InvalidSignature` を 401 に対応付け、有効期限切れとは区別してください。そうすれば、クライアントは決して検証を通らないトークンで再試行しなくなります。

    rust
    use jsonwebtoken::errors::ErrorKind;
    
    match decode::<Claims>(&token, &key, &validation) {
        Ok(data) => Ok(data.claims),
        Err(e) => match e.kind() {
            ErrorKind::InvalidSignature => Err(AuthError::Unauthorized),   // wrong key or tampered token
            ErrorKind::ExpiredSignature => Err(AuthError::Expired),
            _ => Err(AuthError::BadToken),
        },
    }
  2. 2.

    発行者の JWKS から kid で鍵を選択する

    `JwkSet::find` と `DecodingKey::from_jwk` を使うと、発行者がヘッダーで指定した鍵を正確に選択できます。

    rust
    use jsonwebtoken::{decode_header, jwk::JwkSet, DecodingKey};
    
    let header = decode_header(&token)?;
    let kid = header.kid.ok_or(AuthError::BadToken)?;
    let jwk = jwks.find(&kid).ok_or(AuthError::UnknownKey)?; // jwks: JwkSet fetched from the issuer
    let key = DecodingKey::from_jwk(jwk)?;

関連するエラー

署名エラーデータベースをすべて見る