AWS の署名バージョン 4 (SigV4) はどう動いているのか - API 認証の暗号学的な仕組み

AWS API の認証に使われる SigV4 署名プロセスの 4 ステップ (正規リクエスト作成、署名文字列構築、署名キー導出、署名計算) を暗号学的な観点から解説し、SigV4A やプリサインド URL の仕組みも紹介します。

なぜ署名が必要なのか

AWS API へのリクエストには、リクエストの送信者が正当な AWS ユーザーであることを証明する認証情報が必要です。最も単純な認証方式は、アクセスキーとシークレットキーをリクエストに直接含める方法ですが、これは危険です。リクエストが傍受されると、シークレットキーが漏洩します。SigV4 は、シークレットキーをリクエストに含めずに認証を行う署名方式です。シークレットキーを使ってリクエストの内容から署名 (HMAC-SHA256 ハッシュ) を計算し、その署名をリクエストに含めます。AWS 側は、同じシークレットキーを使って同じ計算を行い、署名が一致すれば認証成功です。シークレットキー自体はネットワーク上を流れません。さらに、SigV4 の署名はリクエストの内容 (HTTP メソッド、URL、ヘッダー、ボディ) を含めて計算されるため、リクエストが改ざんされると署名が一致しなくなります。これにより、認証と完全性の両方が保証されます。

署名プロセスの 4 ステップ

SigV4 の署名プロセスは 4 つのステップで構成されます。ステップ 1 は正規リクエスト (Canonical Request) の作成です。HTTP メソッド、URL パス、クエリ文字列、ヘッダー、ボディのハッシュを特定の形式で連結した文字列を作成します。ヘッダーはキーをアルファベット順にソートし、値の前後の空白を除去します。この正規化により、同じリクエストからは常に同じ正規リクエストが生成されます。ステップ 2 は署名文字列 (String to Sign) の構築です。アルゴリズム名 (AWS4-HMAC-SHA256)、タイムスタンプ、クレデンシャルスコープ (日付/リージョン/サービス/aws4_request)、正規リクエストの SHA-256 ハッシュを連結します。ステップ 3 は署名キーの導出です。シークレットキーから、日付、リージョン、サービス名を順番に HMAC-SHA256 で畳み込んで署名キーを生成します。ステップ 4 は署名の計算です。署名キーで署名文字列の HMAC-SHA256 を計算し、16 進数文字列に変換します。この署名を Authorization ヘッダーに含めてリクエストを送信します。

署名キーの導出 - なぜ多段階の HMAC なのか

署名キーの導出は、シークレットキーから 4 段階の HMAC-SHA256 を経て行われます。kDate = HMAC(AWS4 + SecretKey, Date)、kRegion = HMAC(kDate, Region)、kService = HMAC(kRegion, Service)、kSigning = HMAC(kService, aws4_request) です。この多段階の導出には 2 つの目的があります。第 1 に、署名のスコープを限定することです。署名キーは日付、リージョン、サービスに紐づいているため、ある日の東京リージョンの S3 用の署名キーは、別の日や別のリージョンや別のサービスでは使用できません。署名キーが漏洩しても、被害が限定されます。第 2 に、署名キーのキャッシュを可能にすることです。同じ日、同じリージョン、同じサービスへのリクエストでは、署名キーは同じです。SDK は署名キーをキャッシュし、日付が変わるまで再利用します。シークレットキーから毎回署名キーを導出する必要がないため、パフォーマンスが向上します。署名に含まれるタイムスタンプは、AWS のサーバー時刻と 5 分以内の差でなければ拒否されます。これにより、古い署名の再利用 (リプレイ攻撃) が防止されます。

プリサインド URL - 署名を URL に埋め込む

S3 のプリサインド URL は、SigV4 の署名をクエリ文字列に埋め込んだ URL です。この URL を知っている人は、AWS の認証情報なしで S3 オブジェクトにアクセスできます。プリサインド URL には有効期限があり、最大 7 日間 (IAM ユーザーのアクセスキーの場合) または最大 12 時間 (STS の一時認証情報の場合) です。プリサインド URL のクエリ文字列には、X-Amz-Algorithm (署名アルゴリズム)、X-Amz-Credential (アクセスキー ID とクレデンシャルスコープ)、X-Amz-Date (タイムスタンプ)、X-Amz-Expires (有効期限の秒数)、X-Amz-SignedHeaders (署名に含まれたヘッダー)、X-Amz-Signature (署名) が含まれます。プリサインド URL の重要な特性は、URL を生成した時点の権限で評価されるのではなく、URL が使用された時点の権限で評価されることです。URL を生成した後にアクセスキーが無効化されたり、IAM ポリシーが変更されたりすると、URL は使用できなくなります。

SigV4A - マルチリージョン対応の新しい署名方式

SigV4 の署名キーはリージョンに紐づいているため、1 つの署名で複数のリージョンにリクエストを送信することはできません。S3 のマルチリージョンアクセスポイントのように、リクエストが複数のリージョンにルーティングされる可能性がある場合、SigV4 では対応できません。SigV4A (Signature Version 4A) は、この制約を解決するために導入された拡張です。SigV4A は HMAC-SHA256 の代わりに ECDSA (楕円曲線デジタル署名アルゴリズム) を使用します。ECDSA は非対称暗号であるため、署名キーの導出にリージョンを含める必要がありません。1 つの署名で複数のリージョンにリクエストを送信できます。SigV4A は現在、S3 のマルチリージョンアクセスポイントと EventBridge のグローバルエンドポイントで使用されています。SDK は、対象のサービスとエンドポイントに応じて SigV4 と SigV4A を自動的に切り替えるため、開発者が署名方式を意識する必要はほとんどありません。AWS の API 認証を体系的に学ぶには、専門書籍 (Amazon)が参考になります。