本文へスキップ
ecdsa.com
golang-jwt/jwt (Go)Go

エラーメッセージ

token signature is invalid: key is of invalid type: ECDSA verify expects *ecdsa.PublicKey

別の表記

  • token signature is invalid: key is of invalid type: HMAC verify expects []byte
  • token signature is invalid: key is of invalid type: RSA verify expects *rsa.PublicKey
  • key is of invalid type: ECDSA sign expects *ecdsa.PrivateKey
  • key is of invalid type

v5 は想定される型を示します(「ECDSA verify expects *ecdsa.PublicKey」「HMAC verify expects []byte」)。v4 は「key is of invalid type」とだけ出力します。v5 はこれを `ErrTokenSignatureInvalid` として報告するため、一見すると署名の検証失敗のように見えます。

golang-jwt/jwt (Go) — jwt.ErrInvalidKeyType

このエラーの意味

`Keyfunc` が返した値(または `SignedString` に渡した鍵)の Go の型が、トークンのアルゴリズムに合っていません。golang-jwt は鍵に対して型アサーションを行います。ES* の検証には `*ecdsa.PublicKey`、RS*/PS* には `*rsa.PublicKey`、EdDSA には `ed25519.PublicKey`、HS* には `[]byte` が必要で、署名には対応する秘密鍵が必要です。暗号処理は一切実行されていません。鍵の値が正しいかどうかを確かめる段階にすら至っておらず、オブジェクトの種類が間違っていたということです。

発生する理由

修正方法

  1. 1.

    PEM を一度だけ型付きの鍵に解析する

    golang-jwt には、鍵の種類ごとにヘルパーが用意されています。起動時に解析し、Keyfunc からは型付きの鍵を返してください。

    go
    pub, err := jwt.ParseECPublicKeyFromPEM(pemBytes)      // ES256/384/512
    // rsaPub, err := jwt.ParseRSAPublicKeyFromPEM(pemBytes) // RS*/PS*
    // edPub, err := jwt.ParseEdPublicKeyFromPEM(pemBytes)   // EdDSA
    if err != nil {
    	log.Fatal(err)
    }
    token, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) { return pub, nil },
    	jwt.WithValidMethods([]string{"ES256"}))
  2. 2.

    HMAC シークレットを []byte として返す

    シークレットをバイト列に変換し、`WithValidMethods` で HMAC アルゴリズムに固定してください。こうすれば、非対称の `alg` を持つトークンがそのコードパスに到達することはありません。

    go
    secret := []byte(os.Getenv("JWT_HMAC_SECRET")) // []byte, not string
    token, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) { return secret, nil },
    	jwt.WithValidMethods([]string{"HS256"}))

関連するエラー

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