-
Notifications
You must be signed in to change notification settings - Fork 0
MS_JWE
以下の内容で最終確認済み。
https://tools.ietf.org/html/rfc7516
-
JWE は、暗号化のオプション(暗号化された JWT)。
-
認証付き暗号(AEAD)を利用して、以下を保証する。
- 平文の機密性と完全性
- および保護ヘッダと追加認証データ(AAD)の完全性
補足(使いどころ): 実務で JWE が要るのは意外と限られる。
- トークンは通常 TLS で運ばれるため、経路上の秘匿は TLS が担う。
- JWE が効くのは「中継者に中身を見せたくない」場合
(ブラウザを経由する ID トークン、フロントチャネルで渡すリクエスト オブジェクトなど)。よく使われるのは Nested JWT(署名してから暗号化)で、
OpenID Connect のid_token_encrypted_response_algや、
FAPI(Financial API (FAPI))などのプロファイルで登場する。なお、署名の代わりに暗号化を使ってはならない。
AEAD は「鍵を持つ誰か」が作ったことしか示さず、
発行者の特定(否認防止)はできない。
JWE Compact Serialization or JWE JSON Serialization のどちらでも、
基本的にすべて base64url でエンコードされる。
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-256(RSA-OAEPは SHA-1 ベース)鍵の受け渡し(EC) ECDH-ES+A256KWコンテンツ暗号 A256GCM(またはA128CBC-HS256)
JWKをサポートする場合
jwk / kid / jku などで受信者の鍵を示す。
認証付き暗号(AEAD)暗号化アルゴリズムについての知識が必要。
-
encの認証付き暗号(AEAD)操作の暗号化キー
平文を暗号化して暗号文と認証タグ(MAC)を生成するために
使用される認証付き暗号(AEAD)アルゴリズムの対称鍵。 -
algによって暗号化または決定される。- 一部のアルゴリズムでは、空のオクテットシーケンスになる。
enc の認証付き暗号(AEAD)操作によって決定される。
- 平文を暗号化するときに使用される初期化ベクトル値。
- 一部のアルゴリズムでは、空のオクテットシーケンスになる。
補足(重要): AES-GCM では、同じ鍵で IV(nonce)を再利用すると
鍵ストリームが再利用され、平文が復元できるうえ認証鍵まで漏れる。
CEK をメッセージ毎にランダム生成する JWE の通常の使い方では起きないが、
「CEK を固定して使い回す」独自実装をすると即座に破綻する。
- 認証付き暗号(AEAD)操作の認証や完全性保護のためにあり、
暗号化はされないが認証保護の対象である。 - JWE Compact Serialization の場合は使用(存在)せず、
JWE JSON Serialization の場合にのみ使用(存在)。
-
encの認証付き暗号(AEAD)操作によって、- 平文とコンテンツ暗号化キー(CEK)、追加認証データ(AAD)から、
- 暗号文と認証タグを生成する。
-
encの認証付き暗号(AEAD)操作によって、- 平文とコンテンツ暗号化キー(CEK)、追加認証データ(AAD)から、
- 暗号文と認証タグを生成する。
-
一部のアルゴリズムでは認証タグを使用しない場合がある。
暗号化アルゴリズムの以下の要素について理解が必要。
- 基礎用語
- 認証付き暗号(AEAD)
- コンテンツ暗号化キー(CEK)値を決定するための方法。
- この仕様で使用されるキー管理モードには以下のモノがある。
| モード | 内容 |
|---|---|
| キー暗号化 | ハイブリッド暗号化(キー交換)の利用を意図。RSA-OAEP、RSA1_5 などの鍵交換アルゴリズムを使用 |
| キーラッピング | 対称キーラッピングアルゴリズムの利用を意図。鍵ラップ・アルゴリズムを使用 |
| 直接キー契約 | 鍵合意アルゴリズムの利用を意図 |
| キーラッピングによるキー契約 | 対称キーラッピングアルゴリズムの対称鍵に、鍵合意アルゴリズムの利用を意図 |
| 直接暗号化 | CEK 値が当事者間で共有される鍵管理モード |
-
ハイブリッド暗号化(キー交換)の利用を意図したキー管理モード。
-
RSA-OAEP、RSA1_5などの鍵交換アルゴリズムを使用する。 -
以下の参考資料を参照すると、
- 公開鍵: JWK Set を登録(若しくは
jwks_uriで公開) - 秘密鍵: 証明書や JWK Set
となるもよう(鍵交換だが、アリスとボブではなく単なる公開鍵暗号化)。
- 公開鍵: JWK Set を登録(若しくは
-
参考
- Financial API 実装の技術課題 - Qiita
https://qiita.com/TakahikoKawasaki/items/48a9d22205f77db59726 - [前編] IDトークンが分かれば OpenID Connect が分かる - Qiita
https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06
- Financial API 実装の技術課題 - Qiita
- 対称キーラッピングアルゴリズムの利用を意図したキー管理モード。
- 鍵ラップ・アルゴリズムを使用する。
-
A128KW/A192KW/A256KW -
A128GCMKW/A192GCMKW/A256GCMKW
-
鍵合意アルゴリズムの利用を意図したキー管理モード(ECDH-ES)。
対称キーラッピングアルゴリズムの対称鍵に、
鍵合意アルゴリズムの利用を意図したキー管理モード(ECDH-ES+A256KW)。
CEK 値が当事者間で共有される鍵管理モード(dir)。
移行メモ(正誤): 元ページの見出しは
「キーラッピングによる主要契約」となっていたが、
原文は Key Agreement with Key Wrapping であり、
「キーラッピングによる鍵契約(鍵合意)」が正しい。
一覧側の表記に合わせた。
- 構成要素(ヘッダ、キー、初期ベクトル、暗号文、認証タグ(MAC))を
以下のように表現(エンコード)したもの。 - 以下の 2 つの表現(エンコード)方法があり、
どちらでも、構成要素は base64url でエンコードされる。
-
暗号文&認証タグ(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)
-
同じコンテンツを複数の当事者に暗号化することを可能にする。
-
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 オブジェクト。 - これらのパラメタは、受信者毎に共通。
- 認証付き暗号(AEAD)操作によって完全性保護されたヘッダ・パラメタを含む
-
パラメタ
| パラメタ | 内容 |
|---|---|
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)操作。
-
"alg":"RSA-OAEP"- Optimal Asymmetric Encryption Padding - Wikipedia
https://ja.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding - .NET なら、
RSACryptoServiceProvider.Encryptメソッドの
第二引数をtrueに指定すると、OAEP パディングを使用する。
- Optimal Asymmetric Encryption Padding - Wikipedia
-
"enc":"A256GCM"-
アルゴリズム
RFC 7518 - JSON Web Algorithms (JWA)- 5.3. Content Encryption with AES GCM
https://tools.ietf.org/html/rfc7518#section-5.3
- 5.3. Content Encryption with AES GCM
- .NETライブラリ
-
アルゴリズム
補足(最新化): .NET Core 3.0 以降は
System.Security.Cryptography.AesGcmクラスが利用できる。
また RSA の OAEP は次のように書く(RSAEncryptionPadding.OaepSHA256がRSA-OAEP-256)。using var rsa = RSA.Create(); byte[] wrapped = rsa.Encrypt(cek, RSAEncryptionPadding.OaepSHA256);
-
"alg":"RSA1_5"- PKCS - Wikipedia
https://ja.wikipedia.org/wiki/PKCS - RFC 2313 - PKCS #1: RSA Encryption Version 1.5
https://tools.ietf.org/html/rfc2313 - .NET なら、
RSACryptoServiceProvider.Encryptメソッドの
第二引数をfalseに指定すると、PKCS#1 v1.5 パディングを使用する。
- PKCS - Wikipedia
-
"enc":"A128CBC-HS256"-
アルゴリズム
RFC 7518 - JSON Web Algorithms (JWA)- 5.2. AES_CBC_HMAC_SHA2 Algorithms
https://tools.ietf.org/html/rfc7518#section-5.2 - 5.2.3. AES_128_CBC_HMAC_SHA_256
https://tools.ietf.org/html/rfc7518#section-5.2.3
- 5.2. AES_CBC_HMAC_SHA2 Algorithms
-
アルゴリズム
※ 前述の通り、RSA1_5 は新規実装では使用しないこと。
-
"alg":"A128KW"
RFC 3394 - Advanced Encryption Standard (AES) Key Wrap Algorithm
https://tools.ietf.org/html/rfc3394 -
"enc":"A128CBC-HS256"
同上
JWAを参照。
-
JWE Protected Header の決定
{"alg":"RSA-OAEP","enc":"A256GCM"}など。 -
暗号化キーの生成
- ランダムなコンテンツ暗号化キーを生成。
乱数を生成する際の考慮事項については、RFC 4086 を参照 -
alg別- Key Wrapping / Key Encryption / Key Agreement with Key Wrapping
→ 受信者の公開鍵(または共有鍵)で暗号化キーを暗号化したバイト列 - Direct Key Agreement(
ECDH-ES)
→ 空のバイト列とする。 - Direct Encryption(
dir)
→ 空のバイト列とする(CEK は共有済みの対称鍵そのもの)。
- Key Wrapping / Key Encryption / Key Agreement with Key Wrapping
- Base64url エンコードする。
※ JWE JSON Serialization を使用している場合は、上記を繰り返す。
- ランダムなコンテンツ暗号化キーを生成。
-
初期化ベクトルの生成
-
encアルゴリズムに初期化ベクトルが必要な場合
→ ランダムなコンテンツ暗号化の初期化ベクトルを生成。 - 必要でない場合
→ 空のバイト列とする。 - Base64url エンコードする。
-
-
追加の認証データ暗号化パラメタ
- JWE Compact Serialization の場合
ASCII(BASE64URL(UTF8(JWE Protected Header))) - JWE JSON Serialization の場合
ASCII(BASE64URL(UTF8(JWE Protected Header)) || '.' || BASE64URL(JWE AAD))
- JWE Compact Serialization の場合
-
暗号文の生成
- 平文を、必要なら
zipのアルゴリズムで圧縮し、encのアルゴリズムで暗号化する。 - Base64url エンコードする。
- 平文を、必要なら
-
認証タグの生成
- AEAD 操作が、暗号文と同時に認証タグを出力する。
- Base64url エンコードする。
-
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 |
-
RFC 7518 - JSON Web Algorithms (JWA) > 4.3. Key Encryption with RSAES OAEP
https://tools.ietf.org/html/rfc7518#section-4.3 -
openssl - What is a difference between RSA-OAEP and RSAES-OAEP? - Stack Overflow
https://stackoverflow.com/questions/54412865/what-is-a-difference-between-rsa-oaep-and-rsaes-oaep -
OpenTouryo/JWE_RsaOaepAesGcm.cs at develop · OpenTouryoProject/OpenTouryo
https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Frameworks/Infrastructure/Public/Security/JWE_RsaOaepAesGcm.cs
.NETの署名・暗号化アルゴリズムの署名・暗号化アルゴリズムを
使用すると良い。
補足: JWS 以上に、JWE の自作は勧められない。
AEAD の使い方、IV の管理、パディング オラクルの回避など、
誤ると即座に破綻する要素が多い。
.NET ならMicrosoft.IdentityModel.JsonWebTokens、
あるいは jose-jwt のような実績のあるライブラリを使う。
-
RFC 7516 - JSON Web Encryption (JWE)
https://tools.ietf.org/html/rfc7516 -
jose-jwt(ライブラリ)
-
- JWA - JWE用(JWA)
- .NETの署名・暗号化アルゴリズム
Tags: 移行, IT国際標準, プログラミング, 通信技術, 認証基盤, クレームベース認証, 暗号化
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。