t0mmy

2020年12月30日に参加

学習履歴詳細

API デザインパターン 30章 リクエストの認証 読了

やったこと

  • API デザインパターン 30章 リクエストの認証 読了

学んだこと

ポイント

  • APIリクエストを認証するための3要件
  • 上記3要件を満たす認証メカニズム
  • 署名に入力するペイロード
  • トレードオフ

学び

  • APIリクエストを認証する3要件は「発信元の証明」「整合性」「否認防止」
  • デジタル署名は、上記3要件を満たす
  • デジタル署名に入力するペイロードは、リクエスト・フィンガープリントを入力する
    • 「HTTPメソッド」「パス」「ホスト」「HTTPボディのハッシュ値」
  • デジタル署名は、ユースケース次第では過剰な仕組みと判断される
    • 特に「否認防止」機能
    • 否認防止機能が不要な場合、軽量な代替手段を選択できる

メモ

公開鍵の交換とデジタル署名を使用した、全APIリクエストを認証する方法と、その理由を追う。

対象とする問題

APIリクエストが、正規の利用者からのものだとどうやって判断するか。
以下の3つの要件を考慮することで判断する。

  1. 発信元の証明
    • あるユーザーAと称するリクエストが、本当にユーザーAから発信されたリクエストなのか確認する
    • あるユーザーAのみが提供できる情報を確認することで実現する
  2. 整合性
    • 受け取ったリクエスト情報が、(データの破損や改ざんなどで)送信時から変更されていないことを保証する
  3. 否認防止
    • リクエスト送信元が、リクエストを送信した事実を否認できないこと
    • 言い換えると、リクエスト送信元が、確実にリクエストを送信した事実を証明すること

概要

デジタル署名技術は、上記3つの要件をすべて満たしており、本件に最適。
デジタル署名をWeb APIに組み込むには、以下の3ステップが必要。

  1. クライアント側にて、公開鍵・秘密鍵のペアを作成する
  2. クライアントは、生成した公開鍵を、APIサーバー側に登録する
  3. 秘密鍵を使用して、デジタル署名の生成を始める

実装

認証情報の生成

ssh-keygen コマンドなどで、クライアント側にて公開鍵・秘密鍵のペアを作成する。

秘密鍵は、絶対に公開してはならない。

登録と認証情報の交換

生成した公開鍵を、APIサーバー側に登録する。

クライアントは、秘密鍵を使用してデジタル署名を作成し、APIリクエストに添付する。
APIサーバー側は、公開鍵を使用して、デジタル署名を検証できる。

署名の生成と検証

暗号系の標準ライブラリを使用して、デジタル署名を生成できる。
署名の検証も同様に、暗号系の標準ライブラリで検証可能。

リクエスト・フィンガープリント

署名は、リクエスト・フィンガープリントを使用して作成する。

リクエスト・フィンガープリントには、以下の情報を含める。

  • HTTPメソッド
  • URL(ホストとパス)
  • リクエストボディ
    • データサイズが過度に大きくなることを考慮し、ハッシュ値を計算する
    • 計算したハッシュ値を「Digest」と呼ばれる HTTPヘッダー(Base64形式)に格納する

存在するなら、リクエスト送信時間も含めると良い。

  • 古すぎるリクエストを拒否できるようになる

HTTPリクエストに署名するために使用するフィンガープリントの例

(request-target): get /sample/1
host: example.com
date: Tue, 26 Oct 2022 12:00:00 GMT
digest: SHA-256=xxxxxxxx

上記フィンガープリントをペイロードに、デジタル署名を作成する。

署名を持たせる

APIサーバー側で署名を検証できるよう、リクエストに以下のメタデータを含める必要がある。

  • headers フィールド : フィンガープリントに含まれるヘッダーの順序付きリスト
    • ヘッダーの順序によってフィンガープリントは変化するため、順序は大事
  • keyId フィールド : 公開鍵を特定できるID
    • ユーザーIDを使用できる
  • signature フィールド : デジタル署名本体
  • algorithm フィールド: 署名の生成に使用したアルゴリズム

リクエストを検証する

APIサーバー側は、送られてきたメタデータを使用して、以下を検証する。

  • ダイジェストヘッダーを確認し、リクエストが変更されていないことを検証する
  • 公開鍵とフィンガープリントを使用して、署名が正しい事を検証する
    • 事前に、リクエストのフィンガープリントを再計算する必要がある

トレードオフ

デジタル署名は非常に安全な選択肢だが、ユースケース次第では過剰な場合もある。

  • 特に否認防止機能

否認防止が不要な場合、デジタル署名の代わりに、以下代替手段が検討できる。

  • 秘密鍵 & HMAC
  • 短命のアクセストークンを使用した認証メカニズム

デジタル署名は計算量が多い。
この計算量を気にする場合、より軽量な代替手段を選ぶことになる。


扱うこと

  • リクエスト認証システムの要件
  • デジタル署名の概要
  • 認証情報の生成、登録、署名
  • HTTPリクエストのフィンガープリント
  • 署名の詳細を伝える
  • 署名の検証とHTTPリクエストの認証

まとめ

  • リクエストの認証を成功させるには、以下3つの要件がある
    • 発信元の証明 : リクエストが既知のソースから来たことの証明であり、不確実性はない
    • 整合性 : リクエストが、既知の発信元から送信された時点から改変されていないことの証明
    • 否認防止 : リクエスト送信元が、確実にリクエストを送信した事実を証明すること
      • 言い換えると、リクエスト送信元が、リクエストを送信した事実を否認できないこと
  • 認証は、IDが無記名債権のような秘密鍵の所有として定義されることを利用している
  • リクエストに署名するとき、署名されるコンテンツは、以下を含むリクエストのフィンガープリントである必要がある
    • 「HTTPメソッド」「パス」「ホスト」「HTTPボディ内の一連コンテンツ」
WebAPI

2023年12月10日(日)

1.0時間