JSONウェブ署名(JWS) デコードとは、JWSトークンの構成要素(ヘッダー、ペイロード、署名)を解析し、検証するプロセスである。セキュリティと侵入テストの文脈では、JWSをデコードすることは、アナリストがどのような主張が埋め込まれているかを理解し、誤った設定を検出し、署名バイパスやトークン偽造のような脆弱性につながる脆弱な署名の慣行を特定するのに役立ちます。
この記事では、次のように説明している。 JWSデコードが重要な理由実際のコードを使ったシグネチャのデコードと検証方法、よくある落とし穴、セキュリティへの影響、2025年に知っておくべき防御戦略など。
JSONウェブ署名(JWS)とは?
JSONウェブ署名(JWS) は、署名されたメッセージを表現するためのコンパクトでURLセーフな手段である。これは RFC 7515 REST API、シングルサインオン(SSO)、マイクロサービスの認証フローで転送されるデータの真正性と完全性を確保するために一般的に使用されます。
典型的なJWSトークンは次のようなものだ:
nginx
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvZSJ9 .MEUCIQDh...
各セグメントは ベース64URL エンコードされている:
- ヘッダー - アルゴリズムとトークン・タイプを記述する
- ペイロード(クレーム) - 署名されたデータ
- 署名 - 完全性の証明
署名を検証することなくJWSを解読すると、クレームが明らかになるが、検証によってのみ、それが信頼できるソースから来たことが証明される。
権威ある基準: RFC 7515 https://tools.ietf.org/html/rfc7515

なぜJWSをデコードするのか?セキュリティとテストの視点
JWSの解読にはいくつかの目的がある:
- 埋め込まれたクレームを理解する: ユーザーとは?パーミッションとは?
- 署名アルゴリズムを特定する: 弱いアルゴリズム(例.
なしまたはHS256予測可能なキー) - 完全性を評価する: 改ざんされたトークンの検出
- 脆弱性を発見する: シグネチャ・バイパス、アルゴリズム・ダウングレード攻撃
攻撃的なセキュリティの観点からは、脆弱なJWSの署名方法を発見することは、攻撃者がトークンを偽造し、特権を昇格させるエクスプロイトにつながる可能性がある。
JWSトークンの構造
典型的なトークンの内訳は以下の通り:
| セグメント | 意味 | 例 |
|---|---|---|
| ヘッダー | アルゴリズムとメタデータ | { "alg":"RS256", "typ":"JWT"} |
| ペイロード | クレーム | { "sub":"12345", "role":"admin "である。} |
| 署名 | 署名入りダイジェスト | 暗号化されたヘッダー+ペイロードのBase64URL |
デコードされたJWSは、ヘッダーとペイロードのプレーンJSONを示す:
イニ
HeaderJSON = base64url_decode(part1)PayloadJSON = base64url_decode(part2)
解読は真正性を証明するものではなく、署名の検証のみが真正性を証明する。
シンプルなJWSデコード(検証なし)
セキュリティのトリアージでは、多くの場合、最初のステップは中身を見ることだ:
Pythonの例(デコードのみ)
パイソン
import base64import json def base64url_decode(input_str): rem = len(input_str) % 4 input_str += "=" * (4 - rem)return base64.urlsafe_b64decode(input_str) token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMifQ.SflKxw... "header, payload, signature = token.split('.') header_json = json.loads(base64url_decode(header)) payload_json = json.loads(base64url_decode(payload)) print("Header:", header_json)print("Payload:", payload_json)
これは読み取り可能なJSONを出力するが、署名が正しいかどうかは検証しない。
JWS署名の検証(セキュリティ・クリティカル)
トークンが正当なものであると確信するには、期待されるアルゴリズムとキーを使って署名を検証する必要があります。その方法は以下の通り:
JavaScript(Node.js)の使用例 ホセ
ジャバスクリプト
import { jwtVerify } from "jose"; const token = "eyJ..."; const publicKey = /* 適切な公開鍵を読み込む、例えばJWKSエンドポイントから */; async function verifyToken() {try {const { payload } = await jwtVerify(token, publicKey);console.log("Verified payload:", payload); } catch (e) {console.error("Verification failed:", e); }.} verifyToken();
これにより、トークンが公開鍵に対応する正しい秘密鍵によって署名されたことが保証される。
実際の例OAuthトークンのデコード
多くの API はアクセス制御のために JWS トークンを発行する。デコードすると、ユーザーとセッションの情報が明らかになる:
json
{ "iss":"", "sub":"alice", "exp":1700000000, "scope":"読み取り書き込み" }。
セキュリティチームはデコードされたトークンをレビューし、スコープと有効期限を監査する。
JWS実装に共通する脆弱性
アルゴリズムのダウングレード
ライブラリの中には アルグ への なしこれにより、攻撃者は検証をバイパスすることができる。
安全でないヘッダーの例:
json
{"alg":"none","typ":"JWT"}
攻撃防御: を持つトークンは常に拒否される。 alg: なし 文脈上明示的に安全でない限り。
弱い対称鍵 (HS256)
弱い、あるいは予測可能な共通鍵を使用すると、攻撃者は鍵を推測してトークンを偽造することができる。
緩和:
- 強力な秘密鍵を使用する(256ビット以上)
- 非対称アルゴリズムを好む
RS256,ES256)
JWSを素早くデコードするCLIツール
| 工具 | 説明 | 公式 |
|---|---|---|
| jwt.io デバッガ | ウェブベースのデコード&ベリファイ | https://jwt.io |
| ホセ・CLI | ノードベースのデコード/ベリファイ | https://github.com/panva/jose |
| jwt-cli | クロスプラットフォームCLI | https://github.com/mike-engel/jwt-cli |
CLIデコードの例:
バッシュ
jwtデコードeyJhbGciOi...
脆弱性のシナリオトークンの偽造(概念実証)
サーバーが誤って alg: なし攻撃者は偽造できる:
css
ヘッダー{"alg":"none","typ":"JWT"}ペイロード:{"sub":"attacker","role":"admin"}署名:""
概念実証スクリプト(Python):
パイソン
import base64import json def b64url(x): return base64.urlsafe_b64encode(x).rstrip(b'=').decode() header = {"alg": "none", "typ": "JWT"} payload = {"sub": "attacker", "role": "admin"} token = f"{b64url(json.dump(header).encode())}.{b64url(json.dump(payload).encode())}.{b64url(json.dump(header).encode())}.b64url(json.dumps(header).encode())}.{b64url(json.dumps(payload).encode())}. "print("偽造トークン:", token)
ディフェンス
- 以下のトークンを拒否する。
アルグはなし明示的に安全でない限り - アルゴリズム・ホワイトリストの実施

2025年に署名検証が重要な理由
最新のマイクロサービスや分散APIでは、トークンがアクセス決定の原動力となります。不適切な検証は次のような事態を招きます:
- 特権の昇格
- 不正アクセス
- セッション・ハイジャック
ペネトレーション・テスターと防御者は、トークンをプログラム的に、かつ大規模にデコードし、検証できなければならない。
APIで壊れた検証を検出する
自動化されたスキャナは、APIが無効なJWSシグネチャを受け入れようとするかどうかをチェックできる。
Python擬似コード(セキュリティチェック)
パイソン
def test_broken_verification(api_url, forged_token): headers = {"Authorization": f "Bearer {forged_token}"} response = requests.get(api_url, headers=headers)return response.status_code bad_api = test_broken_verification("", forged_token)if bad_api == 200:print("Potentially vulnerable to JWS forgery")
APIが 200 OKトークン受け入れのロジックには欠陥があるかもしれない。
ディフェンスのベストプラクティス
| ディフェンス | 説明 |
|---|---|
| 非対称キーの使用 | 共通鍵よりRS256、ES256を好む |
| アルゴリズムのホワイトリスト化 | 予期しないアルゴリズム値を拒否する |
| 短いトークン寿命 | リプレイ・リスクの最小化 |
| キー回転 | 署名鍵を定期的に更新する |
| 監査トークン・ライブラリ | 依存関係を最新に保つ |
CI/CDセキュリティへのトークン解読の統合
2025年、セキュリティ・パイプラインは、多くの場合、JWSの実践を自動的に検証する:
- JWT設定の自動リンティング
- 安全でないリブを拒否するCIテスト
- 不正トークン受理のランタイム監視
CIスクリプトのスニペット例(Bash):
バッシュ
#Reject if any code uses "alg: none "grep -R '"alg":*"none"' ./src && exit 1
関連コンセプトJWE vs JWS
| 期間 | 意味 |
|---|---|
| JWS | JSONウェブ署名(署名のみ) |
| JWE | JSON ウェブ暗号化 (暗号化) |
JWEは機密性を保護し、JWSは完全性と真正性を保護する。多くのシステムはこの両方を併用している。
ツールとライブラリ(2025年セキュリティスタック)
- Node.js
ホセ- JWT/JWSのデコードと検証 - パイソン
ニシキヘビ- 柔軟な暗号サポート - オープンSSL - 低レベル暗号検証
- jwt.io - クイックウェブデコーダー

