AWS SigV4 Canonical Request ビルダー|中間文字列と 2 種の SHA-256 を 1 画面で確認
HTTP メソッド・URI・クエリ・ヘッダ・ペイロードを入力すると、AWS Signature Version 4 の Canonical Request 文字列、SignedHeaders、ペイロードの SHA-256、そして Canonical Request 自体の SHA-256 を組み立てて表示するツール。多くの SigV4 解説が飛ばす「中間文字列」をそのまま見せるので、SDK が出す署名不一致エラーの原因をこの 1 画面で突き合わせられる。サーバを立てず、貼り付けるだけで確認できる。
💡 このツールについて
AWS SigV4 の署名は、最終的に算出する Signature の前に必ず Canonical Request という中間文字列を経由する。これは「メソッド・正規化した URI・正規化したクエリ・正規化したヘッダブロック・SignedHeaders・ペイロードハッシュ」を改行で連結した、厳密に決まった書式の文字列だ。AWS の SDK や boto3 は内部でこれを組み立ててハッシュするが、自前で署名処理を書くと、この中間文字列のどこか 1 文字がずれただけで SignatureDoesNotMatch が返り、しかもエラー本文は最終ハッシュしか教えてくれないため原因が掴めない。
このツールは入力から Canonical Request を SigV4 の規則どおりに組み立てる。URI とクエリは RFC 3986 のルールで unreserved 文字 (A-Z a-z 0-9 - . _ ~) 以外をパーセントエンコードし、クエリはキーでソート、ヘッダは名前を小文字化して値の連続する空白を 1 つに畳んでから名前順に並べる。そのうえで Canonical Request 本文・SignedHeaders・ペイロード SHA-256・Canonical Request の SHA-256 を同時に出すので、自分の実装が吐いた値とこの 4 つを照合すれば、どの正規化ステップで差が出たかを切り分けられる。
Lambda@Edge や IoT の署名、低レベルな CloudFront ワークフローなど、SDK を使わずに自分で signer を書く場面で、各ステップの中間値を目で確認したいときに向いている。本番リクエストのヘッダをそのまま貼って、SDK の挙動を真似た期待値として使うのが基本の流れだ。
🧐 よくある質問
Canonical Request と StringToSign は何が違う? Canonical Request はリクエスト内容を正規化した文字列で、本ツールが出すのはこちら。StringToSign はそのハッシュにアルゴリズム名・日付・スコープを足した次段の文字列で、署名鍵で HMAC する直前の入力にあたる。本ツールは Canonical Request とその SHA-256 までを担う。
ヘッダはどう正規化される? 名前を小文字化し、値の前後を trim、内部の連続する空白を 1 つに畳んでから、名前のアルファベット順にソートする。同じ名前が複数あればカンマで連結する。SignedHeaders はソート後の名前をセミコロンで連結したものになる。
ペイロードが空のときのハッシュは?
空文字列の SHA-256 である e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 になる。GET や DELETE のように本文がないリクエストではこの値が使われ、ツールも初期状態でこれを表示する。
クエリ文字列のソート順は?
パーセントエンコード後のキーで昇順ソートし、キーが同じなら値で比較する。値のないキー (key だけ) は key= として空値で扱う。この順序が SigV4 の要件で、順序が違うと署名は一致しない。
入力した値はどこかに送られる? 送られない。メソッド・ヘッダ・ペイロードを含むすべての入力はブラウザ内で処理され、SHA-256 も Web Crypto API でローカル計算する。本番の署名対象リクエストをそのまま貼っても外部に出ない。
📚 なぜ署名の前に「正規化」が要るのかの豆知識
SigV4 が Canonical Request という手間をかける理由は、同じ意味のリクエストが複数の表現を持ちうるからだ。クエリ b=2&a=1 と a=1&b=2 は意味が同じでも文字列としては別物で、ヘッダの大文字小文字や余分な空白も送信経路で変わりうる。署名は文字列のハッシュなので、表現が 1 文字でも違えばハッシュは全く別の値になり、検証側で一致しなくなる。そこで「クエリはソート」「ヘッダは小文字化して空白を畳む」「URI はパーセントエンコード」という決まった正規化を両側で必ず通すことで、送信側と AWS 側が同じ表現に辿り着くことを保証している。署名そのものより、署名する前に文字列を一意に固定するこの正規化こそが SigV4 の肝で、自前実装で詰まるのもほぼここに集中する。