MS_OIDCCrypto - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

OpenID Connect - 暗号関連

概要

JWTJWS or JWE を使用する。

詳細

共通

共通鍵暗号化方式(鍵の決め方)

  • aud クレームに含まれる client_id に対応する
    client_secret の UTF-8 オクテットを使用する。

  • aud が複数要素の配列の場合の振る舞いは規定されない
    azpclient_id に対応する client_secret で暗号化されている可能性がある)。

公開鍵暗号化方式(鍵の決め方)

  • 公開鍵は JWK Set で公開する必要がある。
  • JWK Set 中に複数の鍵がある場合、JWSJWE ヘッダに kid が必要。

補足(この 2 つが以降すべての土台): 以降の署名・暗号化・鍵のローテーションは、
すべて「鍵をどこから持ってくるか」がこの 2 つのどちらかに帰着する。

  • 共通鍵方式 … 事前に共有済みの client_secret を鍵に使う(配送不要)
  • 公開鍵方式 … jwks_uri で公開された JWK Set から kid で選ぶ

前者は鍵を配る必要がない代わりに
client_secret を安全に保持できるクライアント(Confidential)でしか使えない

署名(JWS)

共通鍵暗号化方式による署名

MAC ベースの署名

  • 鍵には、client_secret を用いた共通鍵を使用する。

  • JWS ヘッダに alg パラメタ値を設定

  • MAC 鍵は、アルゴリズムの最低限のオクテット長を持つ必要がある。

    • 例えば HS256 では, 最低でも 32 オクテットが必要になる。
    • アルファベットに限定される場合、それ以上のオクテットが必要となる。

補足(「アルファベットに限定される場合」): HS256 は
鍵長 256 ビット(32 バイト)以上を要求する。
client_secret が英数字だけの文字列だと 1 文字あたりの
エントロピーが 8 ビットに満たないため、
32 文字では 256 ビット分の強度に届かない、という趣旨である。

公開鍵暗号化方式による署名

RSA および ECDSA の署名

暗号化(JWE)

共通鍵暗号化方式による暗号化

  • をハッシュし切り詰めた左側を使用する。

  • ハッシュ・アルゴリズムは、以下を用いる。

    • 256 ビット以下の鍵には SHA-256
    • 257-384 ビットの鍵には SHA-384
    • 385-512 ビットの鍵には SHA-512
  • 例えば

    • A128KW
      SHA-256 ハッシュを切り詰めて 128 ビットを取り出す。

    • 512 ビット以上の鍵が必要になった場合
      client_secret から鍵を導出する何らかの拡張仕様を定義する。

公開鍵暗号化方式による暗号化

  • RSA
    ランダムな Content Encryption Key によって JWS を RSA 暗号化アルゴリズムで暗号化する。

  • Elliptic Curve

    • JWE ヘッダの epk に指定する短命な Elliptic Curve 公開鍵を生成する。
    • ECDH-ES アルゴリズムを用い Content Encryption Key の鍵を交換し、
      JWS を暗号化する。

補足(署名してから暗号化する): 本節が一貫して
JWS を暗号化する」と書いているとおり、
OpenID Connect では署名済みの JWS を平文として JWE に包む
(Nested JWT)という順序が決まっている。
先に暗号化してから署名すると、
「誰が署名したか」を復号しないと確認できず、
署名の意味が薄れるためである。

鍵のローテーション

  • jwks_uriJWK Setkid でローテーションする。
  • Cache-Control ヘッダに max-age を含め JWK Set のキャッシュを適切にコントロールする。

署名鍵のローテーション

署名者がローテーションを行う。

  • 署名者は、

    • jwks_uri で、秘密鍵に対応する公開鍵のセットを JWK Set として公開する。
    • JWS ヘッダに、署名に使用した公開鍵(JWK Set 中の kid)を含める
  • 検証者は、

    • jwks_uri で指定した場所から JWK Set を取得する。
    • JWS ヘッダの kid から署名に使用した公開鍵を、上記の JWK Set 中から取得する。
    • 取得した公開鍵を使用して署名の検証を行う。

暗号化鍵のローテーション

復号化を行う主体がローテーションを行う。
(古い鍵が使用される可能性があるため、鍵を暫く保持する)。

  • 復号化を行う主体は、

    • jwks_uri で、秘密鍵のセットを JWK Set として公開する。
  • 暗号化を行う主体は、

    • jwks_uri で指定した場所から JWK Set を取得する。
    • JWE ヘッダに、暗号化に使用した秘密鍵(JWK Set 中の kid)を含める。
  • 復号化を行う主体は、

    • JWE ヘッダの kid から暗号化に使用した秘密鍵を、上記の JWK Set 中から取得する。
    • 取得した秘密鍵を使用して復号化を行う。

移行メモ(用語): 暗号化のローテーションの説明で
jwks_uri で、秘密鍵のセットを JWK Set として公開する」と
書かれているが、公開するのはあくまで公開鍵である
(秘密鍵を公開したら暗号化の意味がなくなる)。
ここでいう「秘密鍵」は
「復号側が持つ秘密鍵に対応する公開鍵」を指しているものと読める。
続く「暗号化に使用した秘密鍵(kid)」も同様に、
「どの鍵ペア向けに暗号化したかを示す kid」の意である。
元の記述は残したうえで注記する。

補足(ローテーションの方向が逆になる理由): 署名は
鍵を持つ側=署名者が回すが、暗号化は
**鍵を持つ側=復号者(受け取る側)**が回す。
どちらも「秘密鍵を持っている側が主導する」という点では同じで、
署名と暗号化で役割が入れ替わるだけである。

参考

本 Wiki 内


Tags: IT国際標準, 認証基盤, クレームベース認証, OAuth

⚠️ **GitHub.com Fallback** ⚠️