Skip to content
nishi_74322014 edited this page Sep 1, 2026 · 1 revision

JWE

概要

以下の内容で最終確認済み。
https://tools.ietf.org/html/rfc7516

  • JWE は、暗号化のオプション(暗号化された JWT)。

    • 暗号化されたデータを JSON(の Base64 URL Encode)形式で
      表現するための仕様
    • 暗号化された SAML アサーションを Connect に移行する
      ユースケースなどが想定される。
  • 認証付き暗号(AEAD)を利用して、以下を保証する。

    • 平文の機密性と完全性
    • および保護ヘッダと追加認証データ(AAD)の完全性

補足(使いどころ): 実務で JWE が要るのは意外と限られる。

  • トークンは通常 TLS で運ばれるため、経路上の秘匿は TLS が担う。
  • JWE が効くのは「中継者に中身を見せたくない」場合
    (ブラウザを経由する ID トークン、フロントチャネルで渡すリクエスト オブジェクトなど)。

よく使われるのは Nested JWT(署名してから暗号化)で、
OpenID Connectid_token_encrypted_response_alg や、
FAPI(Financial API (FAPI))などのプロファイルで登場する。

なお、署名の代わりに暗号化を使ってはならない
AEAD は「鍵を持つ誰か」が作ったことしか示さず、
発行者の特定(否認防止)はできない

構成要素

JWE Compact Serialization or JWE JSON Serialization のどちらでも、
基本的にすべて base64url でエンコードされる。

JOSEヘッダ

JWE の基本的なヘッダ(≒ JWE Compact Serialization の場合の保護ヘッダ)には、
以下のものがある。

ヘッダの例

組み合わせ ヘッダ
RSAES-OAEP and AES GCM {"alg":"RSA-OAEP","enc":"A256GCM"}
RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256 {"alg":"RSA1_5","enc":"A128CBC-HS256"}
AES Key Wrap and AES_128_CBC_HMAC_SHA_256 {"alg":"A128KW","enc":"A128CBC-HS256"}

補足(最新化): alg: RSA1_5(RSAES-PKCS1-v1_5)は
Bleichenbacher 攻撃(パディング オラクル)に対して脆弱であり、
RFC 8725(JWT Best Current Practices)でも使用しないよう求められている。
現在は次を使う。

用途 推奨
鍵の受け渡し(RSA) RSA-OAEP-256RSA-OAEP は SHA-1 ベース)
鍵の受け渡し(EC) ECDH-ES+A256KW
コンテンツ暗号 A256GCM(または A128CBC-HS256

JWKをサポートする場合

jwk / kid / jku などで受信者の鍵を示す。

TLS要件

JWSと同じ

ヘッダ以降

認証付き暗号(AEAD)暗号化アルゴリズムについての知識が必要。

コンテンツ暗号化キー(CEK)

  • enc の認証付き暗号(AEAD)操作の暗号化キー
    平文を暗号化して暗号文と認証タグ(MAC)を生成するために
    使用される認証付き暗号(AEAD)アルゴリズムの対称鍵。

  • alg によって暗号化または決定される。

    • 一部のアルゴリズムでは、空のオクテットシーケンスになる。

enc の認証付き暗号(AEAD)操作によって決定される。

  • 平文を暗号化するときに使用される初期化ベクトル値。
  • 一部のアルゴリズムでは、空のオクテットシーケンスになる。

補足(重要): AES-GCM では、同じ鍵で IV(nonce)を再利用すると
鍵ストリームが再利用され、平文が復元できるうえ認証鍵まで漏れる

CEK をメッセージ毎にランダム生成する JWE の通常の使い方では起きないが、
「CEK を固定して使い回す」独自実装をすると即座に破綻する。

追加認証データ(AAD)

  • 認証付き暗号(AEAD)操作の認証や完全性保護のためにあり、
    暗号化はされないが認証保護の対象である。
  • JWE Compact Serialization の場合は使用(存在)せず、
    JWE JSON Serialization の場合にのみ使用(存在)。

暗号文

  • enc の認証付き暗号(AEAD)操作によって、
    • 平文とコンテンツ暗号化キー(CEK)、追加認証データ(AAD)から、
    • 暗号文と認証タグを生成する。

認証タグ(MAC)

  • enc の認証付き暗号(AEAD)操作によって、

    • 平文とコンテンツ暗号化キー(CEK)、追加認証データ(AAD)から、
    • 暗号文と認証タグを生成する。
  • 一部のアルゴリズムでは認証タグを使用しない場合がある。

詳細

暗号化アルゴリズムの以下の要素について理解が必要。

  • 基礎用語
  • 認証付き暗号(AEAD)

キー管理モード

  • コンテンツ暗号化キー(CEK)値を決定するための方法。
  • この仕様で使用されるキー管理モードには以下のモノがある。
モード 内容
キー暗号化 ハイブリッド暗号化(キー交換)の利用を意図。RSA-OAEPRSA1_5 などの鍵交換アルゴリズムを使用
キーラッピング 対称キーラッピングアルゴリズムの利用を意図。鍵ラップ・アルゴリズムを使用
直接キー契約 鍵合意アルゴリズムの利用を意図
キーラッピングによるキー契約 対称キーラッピングアルゴリズムの対称鍵に、鍵合意アルゴリズムの利用を意図
直接暗号化 CEK 値が当事者間で共有される鍵管理モード

キー暗号化

キーラッピング

  • 対称キーラッピングアルゴリズムの利用を意図したキー管理モード。
  • 鍵ラップ・アルゴリズムを使用する。
    • A128KW / A192KW / A256KW
    • A128GCMKW / A192GCMKW / A256GCMKW

直接キー契約

鍵合意アルゴリズムの利用を意図したキー管理モード(ECDH-ES)。

キーラッピングによるキー契約

対称キーラッピングアルゴリズムの対称鍵に、
鍵合意アルゴリズムの利用を意図したキー管理モード(ECDH-ES+A256KW)。

直接暗号化

CEK 値が当事者間で共有される鍵管理モード(dir)。

移行メモ(正誤): 元ページの見出しは
「キーラッピングによる主要契約」となっていたが、
原文は Key Agreement with Key Wrapping であり、
「キーラッピングによる契約(鍵合意)」が正しい。
一覧側の表記に合わせた。

表現(エンコード)

  • 構成要素(ヘッダ、キー、初期ベクトル、暗号文、認証タグ(MAC))を
    以下のように表現(エンコード)したもの。
  • 以下の 2 つの表現(エンコード)方法があり、
    どちらでも、構成要素は base64url でエンコードされる。

JWE Compact Serialization

  • JWS Compact Serialization

  • 暗号文&認証タグ(MAC)のデータを JSON(の Base64 URL Encode)形式で表現する。


  • ヘッダ(保護ヘッダ).キー.初期ベクトル.暗号文.認証タグ(MAC)

    BASE64URL (UTF-8 (JWE Protected Header))
    .
    BASE64URL(JWE Encrypted Key)
    .
    BASE64URL(JWE Initialization Vector)
    .
    BASE64URL(JWE Ciphertext)
    .
    BASE64URL(JWE Authentication Tag)
    

JWE JSON Serialization

  • JWS JSON Serialization

  • 同じコンテンツを複数の当事者に暗号化することを可能にする。

  • Syntax

    • protected = BASE64URL(UTF8(保護ヘッダ))
    • unprotected = 共有 非保護ヘッダ
    • recipients = 受信者毎に個別の情報
      • header = 個別 非保護ヘッダ
      • encrypted_key = BASE64URL(キー)
    • aad = BASE64URL(追加認証データ(AAD))
    • iv = BASE64URL(初期ベクトル)
    • ciphertext = BASE64URL(暗号文)
    • tag = BASE64URL(認証タグ(MAC))
  • Example

    • Complete JWE JSON Serialization Representation

      {
       "protected":"<integrity-protected shared header contents>",
       "unprotected":"<non-integrity-protected shared header contents>",
       "recipients":[
        {"header":"<per-recipient unprotected header 1 contents>",
         "encrypted_key":"<encrypted key 1 contents>"},
        {"header":"<per-recipient unprotected header N contents>",
         "encrypted_key":"<encrypted key N contents>"}],
       "aad":"<additional authenticated data contents>",
       "iv":"<initialization vector contents>",
       "ciphertext":"<ciphertext contents>",
       "tag":"<authentication tag contents>"
      }
    • JWE Using Flattened JWE JSON Serialization
      受信者が 1 人のみの場合は Flattened JWE JSON Serialization を使える。

      {
       "protected":"<integrity-protected header contents>",
       "unprotected":"<non-integrity-protected header contents>",
       "header":"<more non-integrity-protected header contents>",
       "encrypted_key":"<encrypted key contents>",
       "aad":"<additional authenticated data contents>",
       "iv":"<initialization vector contents>",
       "ciphertext":"<ciphertext contents>",
       "tag":"<authentication tag contents>"
      }

移行メモ: 元ページの見出しは
「JWE Using Flattened JWS JSON Serialization」となっていたが、
RFC 7516 の名称は Flattened JWE JSON Serialization である。

保護ヘッダ・非保護ヘッダ

JOSE ヘッダは、以下のメンバの和集合。

  • JWE Compact Serialization の場合は、JOSE ヘッダ ≒ 保護ヘッダ。
  • JWE JSON Serialization の場合は、
    JOSE ヘッダ ≒ 保護ヘッダ and / or 共有 非保護ヘッダ and / or 個別 非保護ヘッダ

保護ヘッダ

  • 認証された暗号化を利用して、完全性を保証。

    • 認証付き暗号(AEAD)操作によって完全性保護されたヘッダ・パラメタを含む
      JSON オブジェクト。
    • これらのパラメタは、受信者毎に共通。
  • パラメタ

パラメタ 内容
alg 暗号化キーの値を暗号化または決定するために使用される暗号アルゴリズムを識別
enc 認証付き暗号(AEAD)のアルゴリズムを識別
zip 暗号化の前に平文に適用される「圧縮」アルゴリズム
    • {"alg":"RSA-OAEP","enc":"A256GCM"}

補足(zip は使わない): 「圧縮してから暗号化」は
**圧縮率から平文を推測する攻撃(CRIME / BREACH と同種)**を招く。
RFC 8725 も zip の使用に警告しており、
既定では使わないのが正しい。
加えて、展開時に巨大化する「zip bomb」による DoS の入口にもなる。

共有 非保護ヘッダ

JWE JSON Serialization の場合に必要な、受信者毎に共通の非保護ヘッダ。

個別 非保護ヘッダ

JWE JSON Serialization の場合に必要な、受信者毎に個別の非保護ヘッダ。

アルゴリズム

  • alg で、キー生成・交換、
  • enc で、認証付き暗号(AEAD)操作。

RSAES-OAEP and AES GCM

補足(最新化): .NET Core 3.0 以降は
System.Security.Cryptography.AesGcm クラスが利用できる。
また RSA の OAEP は次のように書く(RSAEncryptionPadding.OaepSHA256RSA-OAEP-256)。

using var rsa = RSA.Create();
byte[] wrapped = rsa.Encrypt(cek, RSAEncryptionPadding.OaepSHA256);

RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256

※ 前述の通り、RSA1_5新規実装では使用しないこと。

AES Key Wrap and AES_128_CBC_HMAC_SHA_256

JWAを確認

JWAを参照。

手順

暗号化

  1. JWE Protected Header の決定
    {"alg":"RSA-OAEP","enc":"A256GCM"} など。

  2. 暗号化キーの生成

    • ランダムなコンテンツ暗号化キーを生成。
      乱数を生成する際の考慮事項については、RFC 4086 を参照
    • alg
      • Key Wrapping / Key Encryption / Key Agreement with Key Wrapping
        → 受信者の公開鍵(または共有鍵)で暗号化キーを暗号化したバイト列
      • Direct Key Agreement(ECDH-ES
        → 空のバイト列とする。
      • Direct Encryption(dir
        → 空のバイト列とする(CEK は共有済みの対称鍵そのもの)。
    • Base64url エンコードする。

    ※ JWE JSON Serialization を使用している場合は、上記を繰り返す。

  3. 初期化ベクトルの生成

    • enc アルゴリズムに初期化ベクトルが必要な場合
      → ランダムなコンテンツ暗号化の初期化ベクトルを生成。
    • 必要でない場合
      → 空のバイト列とする。
    • Base64url エンコードする。
  4. 追加の認証データ暗号化パラメタ

    • JWE Compact Serialization の場合
      ASCII(BASE64URL(UTF8(JWE Protected Header)))
    • JWE JSON Serialization の場合
      ASCII(BASE64URL(UTF8(JWE Protected Header)) || '.' || BASE64URL(JWE AAD))
  5. 暗号文の生成

    • 平文を、必要なら zip のアルゴリズムで圧縮し、enc のアルゴリズムで暗号化する。
    • Base64url エンコードする。
  6. 認証タグの生成

    • AEAD 操作が、暗号文と同時に認証タグを出力する。
    • Base64url エンコードする。
  7. Serialization

    • JWE Compact Serialization or JWE JSON Serialization

移行メモ(正誤): 元ページは

  • alg の Direct Encryption を「共有対称鍵のバイト列とする」、
  • 認証タグの生成を「追加の認証データ暗号化パラメタを enc
    アルゴリズムで暗号化する」

としていたが、いずれも実際と異なる。

  • dir(Direct Encryption)では、CEK は共有済みの鍵そのものであり、
    JWE Encrypted Key の欄は空になる(鍵を送らないのが要点)。
  • 認証タグは AAD を暗号化したものではなく、
    AEAD が暗号文と一緒に出力する完全性の値である。
    AAD は認証の入力になるだけで、暗号化はされない。

復号化

暗号化の逆プロセスを行う。

補足(復号時の鉄則): 認証タグの検証に失敗したら、
復号結果を一切使ってはならない
(エラー内容も詳しく返さない)。
「復号してから検証する」「失敗理由で応答を変える」実装は
パディング オラクル攻撃の入口になる。

具体例

アルゴリズムの組み合わせ 参照
RSAES-OAEP and AES GCM RFC 7516 Appendix A.1 https://tools.ietf.org/html/rfc7516#appendix-A.1
RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256 RFC 7516 Appendix A.2 https://tools.ietf.org/html/rfc7516#appendix-A.2
AES Key Wrap and AES_128_CBC_HMAC_SHA_256 RFC 7516 Appendix A.3 https://tools.ietf.org/html/rfc7516#appendix-A.3

自作ライブラリ

署名・暗号化アルゴリズム

.NETの署名・暗号化アルゴリズムの署名・暗号化アルゴリズムを
使用すると良い。

補足: JWS 以上に、JWE の自作は勧められない
AEAD の使い方、IV の管理、パディング オラクルの回避など、
誤ると即座に破綻する要素が多い。
.NET なら Microsoft.IdentityModel.JsonWebTokens
あるいは jose-jwt のような実績のあるライブラリを使う。

参考


Tags: 移行, IT国際標準, プログラミング, 通信技術, 認証基盤, クレームベース認証, 暗号化

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally