エラーメッセージ
The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.
別の表記
- jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.
PyJWT (Python) — jwt.exceptions.InvalidKeyError from HMACAlgorithm.prepare_key
このエラーの意味
PyJWT は、PEM 形式の公開鍵、秘密鍵、または証明書を HMAC アルゴリズム(HS256/384/512)のシークレットとして使うよう求められ、これを拒否しました。このガードが存在するのは、JWT のよく知られた種類のバグがあるためです。検証者が同じ鍵引数で RS/ES と HS の両方のアルゴリズムを受け入れると、公開鍵を知っている人なら誰でも、偽造したトークンに対して有効な HMAC を計算できてしまいます。今回は、許可リストで認められている HMAC アルゴリズムを、トークンのヘッダーが指定していました。
発生する理由
許可リストに HMAC と非対称アルゴリズムが混在している
よくある`algorithms=["RS256", "HS256"]` と公開鍵を組み合わせると、HS256 のトークンはその公開鍵を HMAC シークレットとして使おうとします。それを受け入れると偽造トークンが通ってしまうため、PyJWT がこれを止めています。
サービスが HS256 用に設定されているのに PEM を保持している
ときどき`JWT_ALGORITHM=HS256` となっている一方で、`JWT_KEY` に PEM ファイルが入っている設定です。発行者が実際に使っている方式を見極め、両方の値を一致させてください。
誰かが検証者を試している
ときどきRSA や ECDSA で署名する発行者の API に `alg: "HS256"` のトークンが届くのは、アルゴリズム混同の弱点を狙った典型的なプローブです。送信元をログに記録してください。このエラーは、そのプローブが失敗したことを意味します。
修正方法
- 1.
1 つの鍵には 1 つのアルゴリズム系統だけを許可する
発行者の公開鍵と一緒に渡すのは、その発行者が使う非対称アルゴリズムだけにしてください。HMAC による検証は(そもそも必要であれば)、専用のランダムなシークレットを使う別のコードパスに分けてください。
python # Asymmetric issuer: allow only asymmetric algorithms with the public key. claims = jwt.decode(token, public_key, algorithms=["ES256"], audience="https://api.example.com") # Shared-secret tokens: a random secret, never a PEM, and only HMAC algorithms. claims = jwt.decode(token, HMAC_SECRET, algorithms=["HS256"], audience="internal")