RFC 7516

JSON Web Encryption (JWE)

πŸ“… published May 2015, from ietf

RFC 7516: JSON Web Encryption (JWE) πŸŽ€

Okay bestie, this is RFC 7516, the spec for JSON Web Encryption (JWE), and it's giving "seal your secrets inside JSON" energy πŸ”βœ¨

  • Authors: M. Jones (Microsoft) and J. Hildebrand (Cisco) πŸ’œ
  • Category: Standards Track
  • ISSN: 2070-1721
  • Date: May 2015 πŸ“…
  • Obsoletes / Updates: the title block doesn't list anything this RFC obsoletes or updates πŸ™ˆ

Abstract πŸ¦‹

So JWE represents encrypted content using JSON-based data structures, and the actual algorithms and identifiers you can use with it live in the separate JSON Web Algorithms (JWA) spec plus the IANA registries that spec defines. Digital signature and Message Authentication Code (MAC) stuff is handled in the separate JSON Web Signature (JWS) spec. Think of this doc as the encryption-packaging bit, with the other two specs doing the heavy cryptography lifting πŸ’…

Status of This Memo πŸ“œ

This is an Internet Standards Track document, so it's an official standard, not just a vibe 😀

It's a product of the Internet Engineering Task Force (IETF), it reflects the consensus of the IETF community, it got public review, and the Internet Engineering Steering Group (IESG) approved it for publication. If you want the deets on how Internet Standards work, check out Section 2 of RFC 5741 🌸

For the current status, any errata, and where to send feedback, go to http://www.rfc-editor.org/info/rfc7516 πŸ”—

Copyright (c) 2015 belongs to the IETF Trust and the people listed as document authors, and all rights are reserved πŸ”’

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which you can find at http://trustee.ietf.org/license-info as they stood on the publication date. Read them carefully, because they spell out what you're allowed to do with this doc 🧐

If you pull Code Components out of this document, they have to include the Simplified BSD License text described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as the Simplified BSD License describes 🫢

Table of Contents πŸ—‚οΈ

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   4
  1.1.  Notational Conventions  . . . . . . . . . . . . . . . . .   4
2.  Terminology . . . . . . . . . . . . . . . . . . . . . . . . .   5
3.  JSON Web Encryption (JWE) Overview  . . . . . . . . . . . . .   8
  3.1.  JWE Compact Serialization Overview  . . . . . . . . . . .   8
  3.2.  JWE JSON Serialization Overview . . . . . . . . . . . . .   9
  3.3.  Example JWE . . . . . . . . . . . . . . . . . . . . . . .  10
4.  JOSE Header . . . . . . . . . . . . . . . . . . . . . . . . .  11
  4.1.  Registered Header Parameter Names . . . . . . . . . . . .  11
    4.1.1.  "alg" (Algorithm) Header Parameter  . . . . . . . . .  12
    4.1.2.  "enc" (Encryption Algorithm) Header Parameter . . . .  12
    4.1.3.  "zip" (Compression Algorithm) Header Parameter  . . .  12
    4.1.4.  "jku" (JWK Set URL) Header Parameter  . . . . . . . .  13
    4.1.5.  "jwk" (JSON Web Key) Header Parameter . . . . . . . .  13
    4.1.6.  "kid" (Key ID) Header Parameter . . . . . . . . . . .  13
    4.1.7.  "x5u" (X.509 URL) Header Parameter  . . . . . . . . .  13
    4.1.8.  "x5c" (X.509 Certificate Chain) Header Parameter  . .  13
    4.1.9.  "x5t" (X.509 Certificate SHA-1 Thumbprint) Header
            Parameter . . . . . . . . . . . . . . . . . . . . . .  14
    4.1.10. "x5t#S256" (X.509 Certificate SHA-256 Thumbprint)
            Header Parameter  . . . . . . . . . . . . . . . . . .  14
    4.1.11. "typ" (Type) Header Parameter . . . . . . . . . . . .  14
    4.1.12. "cty" (Content Type) Header Parameter . . . . . . . .  14
    4.1.13. "crit" (Critical) Header Parameter  . . . . . . . . .  14
  4.2.  Public Header Parameter Names . . . . . . . . . . . . . .  14
  4.3.  Private Header Parameter Names  . . . . . . . . . . . . .  15
5.  Producing and Consuming JWEs  . . . . . . . . . . . . . . . .  15
  5.1.  Message Encryption  . . . . . . . . . . . . . . . . . . .  15
  5.2.  Message Decryption  . . . . . . . . . . . . . . . . . . .  17
  5.3.  String Comparison Rules . . . . . . . . . . . . . . . . .  20
6.  Key Identification  . . . . . . . . . . . . . . . . . . . . .  20
7.  Serializations  . . . . . . . . . . . . . . . . . . . . . . .  20
  7.1.  JWE Compact Serialization . . . . . . . . . . . . . . . .  20
  7.2.  JWE JSON Serialization  . . . . . . . . . . . . . . . . .  20
    7.2.1.  General JWE JSON Serialization Syntax . . . . . . . .  21
    7.2.2.  Flattened JWE JSON Serialization Syntax . . . . . . .  23
8.  TLS Requirements  . . . . . . . . . . . . . . . . . . . . . .  24
9.  Distinguishing between JWS and JWE Objects  . . . . . . . . .  24
10. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  25
  10.1.  JSON Web Signature and Encryption Header Parameters
         Registration . . . . . . . . . . . . . . . . . . . . . .  25
    10.1.1.  Registry Contents  . . . . . . . . . . . . . . . . .  25
11. Security Considerations . . . . . . . . . . . . . . . . . . .  27
  11.1.  Key Entropy and Random Values  . . . . . . . . . . . . .  27
  11.2.  Key Protection . . . . . . . . . . . . . . . . . . . . .  27
  11.3.  Using Matching Algorithm Strengths . . . . . . . . . . .  28
  11.4.  Adaptive Chosen-Ciphertext Attacks . . . . . . . . . . .  28
  11.5.  Timing Attacks . . . . . . . . . . . . . . . . . . . . .  28
12. References  . . . . . . . . . . . . . . . . . . . . . . . . .  29
  12.1.  Normative References . . . . . . . . . . . . . . . . . .  29
  12.2.  Informative References . . . . . . . . . . . . . . . . .  30
Appendix A.  JWE Examples . . . . . . . . . . . . . . . . . . . .  32
  A.1.  Example JWE using RSAES-OAEP and AES GCM  . . . . . . . .  32
    A.1.1.  JOSE Header . . . . . . . . . . . . . . . . . . . . .  32
    A.1.2.  Content Encryption Key (CEK)  . . . . . . . . . . . .  32
    A.1.3.  Key Encryption  . . . . . . . . . . . . . . . . . . .  33
    A.1.4.  Initialization Vector . . . . . . . . . . . . . . . .  34
    A.1.5.  Additional Authenticated Data . . . . . . . . . . . .  35
    A.1.6.  Content Encryption  . . . . . . . . . . . . . . . . .  35
    A.1.7.  Complete Representation . . . . . . . . . . . . . . .  36
    A.1.8.  Validation  . . . . . . . . . . . . . . . . . . . . .  36
  A.2.  Example JWE using RSAES-PKCS1-v1_5 and
        AES_128_CBC_HMAC_SHA_256  . . . . . . . . . . . . . . . .  36
    A.2.1.  JOSE Header . . . . . . . . . . . . . . . . . . . . .  37
    A.2.2.  Content Encryption Key (CEK)  . . . . . . . . . . . .  37
    A.2.3.  Key Encryption  . . . . . . . . . . . . . . . . . . .  38
    A.2.4.  Initialization Vector . . . . . . . . . . . . . . . .  39
    A.2.5.  Additional Authenticated Data . . . . . . . . . . . .  40
    A.2.6.  Content Encryption  . . . . . . . . . . . . . . . . .  40
    A.2.7.  Complete Representation . . . . . . . . . . . . . . .  40
    A.2.8.  Validation  . . . . . . . . . . . . . . . . . . . . .  41
  A.3.  Example JWE Using AES Key Wrap and
        AES_128_CBC_HMAC_SHA_256  . . . . . . . . . . . . . . . .  41
    A.3.1.  JOSE Header . . . . . . . . . . . . . . . . . . . . .  41
    A.3.2.  Content Encryption Key (CEK)  . . . . . . . . . . . .  42
    A.3.3.  Key Encryption  . . . . . . . . . . . . . . . . . . .  42
    A.3.4.  Initialization Vector . . . . . . . . . . . . . . . .  42
    A.3.5.  Additional Authenticated Data . . . . . . . . . . . .  43
    A.3.6.  Content Encryption  . . . . . . . . . . . . . . . . .  43
    A.3.7.  Complete Representation . . . . . . . . . . . . . . .  43
    A.3.8.  Validation  . . . . . . . . . . . . . . . . . . . . .  44
  A.4.  Example JWE Using General JWE JSON Serialization  . . . .  44
    A.4.1.  JWE Per-Recipient Unprotected Headers . . . . . . . .  45
    A.4.2.  JWE Protected Header  . . . . . . . . . . . . . . . .  45
    A.4.3.  JWE Shared Unprotected Header . . . . . . . . . . . .  45
    A.4.4.  Complete JOSE Header Values . . . . . . . . . . . . .  45
    A.4.5.  Additional Authenticated Data . . . . . . . . . . . .  46
    A.4.6.  Content Encryption  . . . . . . . . . . . . . . . . .  46
    A.4.7.  Complete JWE JSON Serialization Representation  . . .  47
  A.5.  Example JWE Using Flattened JWE JSON Serialization  . . .  47
Appendix B.  Example AES_128_CBC_HMAC_SHA_256 Computation . . . .  48
  B.1.  Extract MAC_KEY and ENC_KEY from Key  . . . . . . . . . .  48
  B.2.  Encrypt Plaintext to Create Ciphertext  . . . . . . . . .  49
  B.3.  64-Bit Big-Endian Representation of AAD Length  . . . . .  49
  B.4.  Initialization Vector Value . . . . . . . . . . . . . . .  49
  B.5.  Create Input to HMAC Computation  . . . . . . . . . . . .  50
  B.6.  Compute HMAC Value  . . . . . . . . . . . . . . . . . . .  50
  B.7.  Truncate HMAC Value to Create Authentication Tag  . . . .  50
Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .  50
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  51

1. Introduction ✨

JWE is how you wrap up encrypted content using JSON-based data structures [RFC7159] 🎁 The JWE cryptographic mechanisms do two jobs at once: they encrypt an arbitrary sequence of octets and they provide integrity protection for it, so nobody can quietly mess with it πŸ”

There are two closely related serializations for JWEs. The JWE Compact Serialization is a compact, URL-safe representation made for space-constrained spots like HTTP Authorization headers and URI query parameters πŸ¦‹ The JWE JSON Serialization represents JWEs as JSON objects instead, and it lets the same content be encrypted to multiple parties at once. Both of them share the same cryptographic underpinnings, so it's the same security under two outfits πŸ‘‘

The algorithms and identifiers you can actually use with this spec are described in the separate JSON Web Algorithms (JWA) [JWA] spec and the IANA registries that spec defines. Digital signature and MAC capabilities are covered in the separate JSON Web Signature (JWS) [JWS] spec πŸ’…

Names defined by this specification are short on purpose, because a core goal is for the resulting representations to be compact 🌸

1.1. Notational Conventions πŸ“

Okay, pay attention, this part is important πŸ™ˆ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be read the way "Key words for use in RFCs to Indicate Requirement Levels" [RFC2119] describes. Those words only carry that special meaning when they appear in all capital letters, so lowercase versions are just regular words 🧠

BASE64URL(OCTETS) means the base64url encoding of OCTETS, following Section 2 of [JWS] πŸ”€

UTF8(STRING) means the octets of the UTF-8 [RFC3629] representation of STRING, where STRING is a sequence of zero or more Unicode [UNICODE] characters 🌈

ASCII(STRING) means the octets of the ASCII [RFC20] representation of STRING, where STRING is a sequence of zero or more ASCII characters πŸ“

Concatenating two values A and B is written as A || B 🧚


2. Terminology ✨

okay bestie, let's get the vocab down first πŸ§ πŸ’… some of these terms are borrowed from the JWS spec, so they're not new to us:

"JSON Web Signature (JWS)", "Base64url Encoding", "Collision-Resistant Name", "Header Parameter", "JOSE Header", and "StringOrURI" are defined by the JWS specification [JWS].

"Ciphertext", "Digital Signature", "Initialization Vector (IV)", "Message Authentication Code (MAC)", and "Plaintext" come from the "Internet Security Glossary, Version 2" [RFC4949] πŸ“š

these ones are defined by this specification, so pay attention πŸ‘€πŸ«Ά

JSON Web Encryption (JWE) A data structure representing an encrypted and integrity-protected message. πŸ”

Authenticated Encryption with Associated Data (AEAD) An AEAD algorithm is one that encrypts the plaintext, allows Additional Authenticated Data to be specified, and provides an integrated content integrity check over the ciphertext and Additional Authenticated Data. It takes two inputs, the plaintext and the Additional Authenticated Data value, and gives back two outputs, the ciphertext and the Authentication Tag value. AES Galois/Counter Mode (GCM) is one such algorithm ✨

Additional Authenticated Data (AAD) An input to an AEAD operation that is integrity protected but not encrypted. 🧾

Authentication Tag An output of an AEAD operation that ensures the integrity of the ciphertext and the Additional Authenticated Data. Some algorithms may not use an Authentication Tag, in which case this value is the empty octet sequence. 🏷️

Content Encryption Key (CEK) A symmetric key for the AEAD algorithm used to encrypt the plaintext to produce the ciphertext and the Authentication Tag. πŸ—οΈ

JWE Encrypted Key Encrypted Content Encryption Key value. For some algorithms, the JWE Encrypted Key value is specified as being the empty octet sequence. πŸ”‘

JWE Initialization Vector Initialization Vector value used when encrypting the plaintext. Some algorithms may not use an Initialization Vector, in which case this value is the empty octet sequence. 🌱

JWE AAD Additional value to be integrity protected by the authenticated encryption operation. This can only be present when using the JWE JSON Serialization. (Note that this can also be achieved when using either the JWE Compact Serialization or the JWE JSON Serialization by including the AAD value as an integrity-protected Header Parameter value, but at the cost of the value being double base64url encoded.) πŸ™ˆ

JWE Ciphertext Ciphertext value resulting from authenticated encryption of the plaintext with Additional Authenticated Data. 🌸

JWE Authentication Tag Authentication Tag value resulting from authenticated encryption of the plaintext with Additional Authenticated Data. πŸ’œ

JWE Protected Header A JSON object that contains the Header Parameters that are integrity protected by the authenticated encryption operation. These parameters apply to all recipients of the JWE. For the JWE Compact Serialization, this comprises the entire JOSE Header. For the JWE JSON Serialization, this is one component of the JOSE Header. πŸ›‘οΈ

JWE Shared Unprotected Header A JSON object that contains the Header Parameters that apply to all recipients of the JWE and are not integrity protected. This can only be present when using the JWE JSON Serialization. 🀝

JWE Per-Recipient Unprotected Header A JSON object that contains Header Parameters that apply to a single recipient of the JWE. These Header Parameter values are not integrity protected. This can only be present when using the JWE JSON Serialization. πŸŽ€

JWE Compact Serialization A representation of the JWE as a compact, URL-safe string. πŸͺΆ

JWE JSON Serialization A representation of the JWE as a JSON object. It lets the same content be encrypted to multiple parties. This representation is neither optimized for compactness nor URL safe, so it's the extra-fancy one πŸ’…

Key Management Mode A method of determining the Content Encryption Key value to use. Each algorithm used for determining the CEK value uses a specific Key Management Mode. The Key Management Modes employed by this specification are Key Encryption, Key Wrapping, Direct Key Agreement, Key Agreement with Key Wrapping, and Direct Encryption. πŸ—ΊοΈ

Key Encryption A Key Management Mode in which the CEK value is encrypted to the intended recipient using an asymmetric encryption algorithm. πŸ”“

Key Wrapping A Key Management Mode in which the CEK value is encrypted to the intended recipient using a symmetric key wrapping algorithm. 🎁

Direct Key Agreement A Key Management Mode in which a key agreement algorithm is used to agree upon the CEK value. πŸ€™

Key Agreement with Key Wrapping A Key Management Mode in which a key agreement algorithm is used to agree upon a symmetric key. That symmetric key is then used to encrypt the CEK value to the intended recipient using a symmetric key wrapping algorithm. It's giving double protection 🧁

Direct Encryption A Key Management Mode in which the CEK value used is the secret symmetric key value shared between the parties. 🫱🫲


3. JSON Web Encryption (JWE) Overview πŸ¦‹

okay so JWE represents encrypted content using JSON data structures and base64url encoding 🌈 these JSON data structures MAY contain whitespace and/or line breaks before or after any JSON values or structural characters, in accordance with Section 2 of RFC 7159 [RFC7159]. totally optional fashion 🧚

a JWE represents these logical values (each of which is defined in Section 2):

  • JOSE Header
  • JWE Encrypted Key
  • JWE Initialization Vector
  • JWE AAD
  • JWE Ciphertext
  • JWE Authentication Tag

for a JWE, the JOSE Header members are the union of the members of these values (each of which is defined in Section 2):

  • JWE Protected Header
  • JWE Shared Unprotected Header
  • JWE Per-Recipient Unprotected Header

JWE uses authenticated encryption to keep the confidentiality and integrity of the plaintext, plus the integrity of the JWE Protected Header and the JWE AAD. that's a whole lotta protection, bestie πŸ”βœ¨

this document defines two serializations for JWEs: a compact, URL-safe serialization called the JWE Compact Serialization, and a JSON serialization called the JWE JSON Serialization. in both serializations, the JWE Protected Header, JWE Encrypted Key, JWE Initialization Vector, JWE Ciphertext, and JWE Authentication Tag are base64url encoded, since JSON has no way to directly represent arbitrary octet sequences πŸ™ƒ when present, the JWE AAD is also base64url encoded.


3.1. JWE Compact Serialization Overview πŸͺΆ

in the JWE Compact Serialization, no JWE Shared Unprotected Header or JWE Per-Recipient Unprotected Header are used. in this case, the JOSE Header and the JWE Protected Header are the same. simple and iconic πŸ’–

in the JWE Compact Serialization, a JWE is represented as the concatenation:

BASE64URL(UTF8(JWE Protected Header)) || '.' ||
BASE64URL(JWE Encrypted Key) || '.' ||
BASE64URL(JWE Initialization Vector) || '.' ||
BASE64URL(JWE Ciphertext) || '.' ||
BASE64URL(JWE Authentication Tag)

see Section 7.1 for more info about the JWE Compact Serialization πŸ“–


3.2. JWE JSON Serialization Overview 🌷

in the JWE JSON Serialization, one or more of the JWE Protected Header, JWE Shared Unprotected Header, and JWE Per-Recipient Unprotected Header MUST be present. in this case, the members of the JOSE Header are the union of the members of the JWE Protected Header, JWE Shared Unprotected Header, and JWE Per-Recipient Unprotected Header values that are present. so at least one of those has to show up, no exceptions 😀

in the JWE JSON Serialization, a JWE is represented as a JSON object containing some or all of these eight members:

"protected", with the value BASE64URL(UTF8(JWE Protected Header))
"unprotected", with the value JWE Shared Unprotected Header
"header", with the value JWE Per-Recipient Unprotected Header
"encrypted_key", with the value BASE64URL(JWE Encrypted Key)
"iv", with the value BASE64URL(JWE Initialization Vector)
"ciphertext", with the value BASE64URL(JWE Ciphertext)
"tag", with the value BASE64URL(JWE Authentication Tag)
"aad", with the value BASE64URL(JWE AAD)

the six base64url-encoded result strings and the two unprotected JSON object values are represented as members within a JSON object. the inclusion of some of these values is OPTIONAL πŸŽ€ the JWE JSON Serialization can also encrypt the plaintext to multiple recipients, which is very main character energy πŸ‘‘ see Section 7.2 for more info about the JWE JSON Serialization.


3.3. Example JWE πŸ’…

this example encrypts the plaintext "The true sign of intelligence is not knowledge but imagination." to the recipient. this quote is so iconic 😭🌟

the following example JWE Protected Header declares that:

  • The Content Encryption Key is encrypted to the recipient using the RSAES-OAEP [RFC3447] algorithm to produce the JWE Encrypted Key.
  • Authenticated encryption is performed on the plaintext using the AES GCM [AES] [NIST.800-38D] algorithm with a 256-bit key to produce the ciphertext and the Authentication Tag.
{"alg":"RSA-OAEP","enc":"A256GCM"}

encoding this JWE Protected Header as BASE64URL(UTF8(JWE Protected Header)) gives this value:

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ

the remaining steps to finish creating this JWE are:

  • Generate a random Content Encryption Key (CEK).
  • Encrypt the CEK with the recipient's public key using the RSAES-OAEP algorithm to produce the JWE Encrypted Key.
  • Base64url-encode the JWE Encrypted Key.
  • Generate a random JWE Initialization Vector.
  • Base64url-encode the JWE Initialization Vector.
  • Let the Additional Authenticated Data encryption parameter be ASCII(BASE64URL(UTF8(JWE Protected Header))).
  • Perform authenticated encryption on the plaintext with the AES GCM algorithm using the CEK as the encryption key, the JWE Initialization Vector, and the Additional Authenticated Data value, requesting a 128-bit Authentication Tag output.
  • Base64url-encode the ciphertext.
  • Base64url-encode the Authentication Tag.
  • Assemble the final representation: The Compact Serialization of this result is the string BASE64URL(UTF8(JWE Protected Header)) || '.' || BASE64URL(JWE Encrypted Key) || '.' || BASE64URL(JWE Initialization Vector) || '.' || BASE64URL(JWE Ciphertext) || '.' || BASE64URL(JWE Authentication Tag).

the final result in this example (with line breaks for display purposes only) is:

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.
OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGe
ipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDb
Sv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaV
mqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je8
1860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi
6UklfCpIMfIjf7iGdXKHzg.
48V1_ALb6US04U3b.
5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6ji
SdiwkIr3ajwQzaBtQD_A.
XFBoMYUZodetZdvTiFvSkQ

see Appendix A.1 for the complete details of computing this JWE. see Appendix A for additional examples, including examples using the JWE JSON Serialization in Sections A.4 and A.5 🫢✨

4. JOSE Header ✨

okay so for a JWE, the members of the JSON object(s) that make up the JOSE Header are where all the encryption tea gets spilled about the plaintext, plus any extra bonus properties of the JWE πŸ’… The Header Parameter names inside the JOSE Header MUST be unique, just like Section 4 of [JWS] spells out. The rules for handling Header Parameters your implementation doesn't understand are the same, and so are the classes of Header Parameter names. consistency is giving πŸŽ€

4.1. Registered Header Parameter Names

these are the Header Parameter names for JWEs that are registered in the IANA "JSON Web Signature and Encryption Header Parameters" registry set up by [JWS], and each one means exactly what's described below πŸ¦‹

okay but here's the lowkey important bit: JWSs and JWEs share one common Header Parameter space πŸ‘‘ so if a parameter gets used by both specs, its usage has to be compatible between them. no drama, just vibes 🫢

4.1.1. "alg" (Algorithm) Header Parameter

this one has the same meaning, syntax, and processing rules as the alg Header Parameter from Section 4.1.1 of [JWS], except that here it names the cryptographic algorithm used to encrypt or to determine the value of the CEK πŸ” the encrypted content is not usable if the alg value isn't a supported algorithm, or if the recipient doesn't have a key that works with that algorithm. πŸ’€

the defined alg values for this use live in the IANA "JSON Web Signature and Encryption Algorithms" registry set up by [JWA]. its initial contents are the values from Section 4.1 of [JWA] ✨

4.1.2. "enc" (Encryption Algorithm) Header Parameter

the enc (encryption algorithm) Header Parameter tells you which content encryption algorithm did the authenticated encryption on the plaintext to make the ciphertext and the Authentication Tag 🌸 this algorithm MUST be an AEAD algorithm with a specified key length, no exceptions bestie 😭 the encrypted content is not usable if the enc value isn't a supported algorithm. enc values should either be registered in the IANA "JSON Web Signature and Encryption Algorithms" registry set up by [JWA], or be a value that contains a Collision-Resistant Name. the enc value is a case-sensitive ASCII string containing a StringOrURI value. this Header Parameter MUST be present, and MUST be understood and processed by implementations. it's literally a must-have 🧚

the defined enc values for this use can be found in that same IANA registry, and its initial contents are the values from Section 5.1 of [JWA] πŸ“

4.1.3. "zip" (Compression Algorithm) Header Parameter

the zip (compression algorithm) is what gets applied to the plaintext before encryption, if there's any at all 🌈 the zip value defined by this spec is:

  • "DEF" - Compression with the DEFLATE [RFC1951] algorithm

other values MAY be used πŸ’œ compression algorithm values can be registered in the IANA "JSON Web Encryption Compression Algorithms" registry set up by [JWA]. the zip value is a case-sensitive string. if there's no zip parameter, no compression gets applied to the plaintext before encryption πŸ™ˆ when it IS used, this Header Parameter MUST be integrity protected, which is why it MUST occur only within the JWE Protected Header. using it is OPTIONAL. and this Header Parameter MUST be understood and processed by implementations ✨

4.1.4. "jku" (JWK Set URL) Header Parameter

this one means the same thing, has the same syntax, and follows the same processing rules as the jku Header Parameter from Section 4.1.2 of [JWS]. the difference is that the JWK Set resource holds the public key the JWE was encrypted to, which can help you figure out the private key you need to decrypt it πŸ”‘

4.1.5. "jwk" (JSON Web Key) Header Parameter

same meaning, syntax, and processing rules as the jwk Header Parameter from Section 4.1.3 of [JWS], except the key here is the public key the JWE was encrypted to. this can be used to find the private key needed to decrypt the JWE πŸ—οΈ

4.1.6. "kid" (Key ID) Header Parameter

this is the same as the kid Header Parameter in Section 4.1.4 of [JWS], except the key hint points at the public key the JWE was encrypted to, which helps you find the private key to decrypt it. this parameter also lets originators explicitly signal a change of key to JWE recipients, which is such a clean move πŸ¦‹

4.1.7. "x5u" (X.509 URL) Header Parameter

same meaning, syntax, and processing rules as the x5u Header Parameter in Section 4.1.5 of [JWS], except the X.509 public key certificate or certificate chain [RFC5280] holds the public key the JWE was encrypted to. this can be used to determine the private key needed to decrypt the JWE 🌸

4.1.8. "x5c" (X.509 Certificate Chain) Header Parameter

this one matches the x5c Header Parameter from Section 4.1.6 of [JWS] in meaning, syntax, and processing rules, except the X.509 public key certificate or certificate chain [RFC5280] contains the public key the JWE was encrypted to. it can be used to find the private key needed to decrypt the JWE πŸŽ€

for an example x5c value, check out Appendix B of [JWS] ✨

4.1.9. "x5t" (X.509 Certificate SHA-1 Thumbprint) Header Parameter

same meaning, syntax, and processing rules as the x5t Header Parameter in Section 4.1.7 of [JWS], except the certificate referenced by the thumbprint contains the public key the JWE was encrypted to. this can be used to determine the private key needed to decrypt the JWE. fun fact: certificate thumbprints are also sometimes called certificate fingerprints 🧚

4.1.10. "x5t#S256" (X.509 Certificate SHA-256 Thumbprint) Header Parameter

this is the same as the x5t#S256 Header Parameter from Section 4.1.8 of [JWS], except the certificate referenced by the thumbprint holds the public key the JWE was encrypted to. it can be used to find the private key needed to decrypt the JWE πŸ“ and yep, certificate thumbprints are also sometimes known as certificate fingerprints πŸ’…

4.1.11. "typ" (Type) Header Parameter

same meaning, syntax, and processing rules as the typ Header Parameter from Section 4.1.9 of [JWS], except the type is the type of this complete JWE 🌈

4.1.12. "cty" (Content Type) Header Parameter

same as the cty Header Parameter from Section 4.1.10 of [JWS], except the type here is the type of the secured content, which is the plaintext πŸ’œ

4.1.13. "crit" (Critical) Header Parameter

this is the same as the crit Header Parameter from Section 4.1.11 of [JWS], with one twist: it's referring to Header Parameters for a JWE, not for a JWS πŸ™ˆ

4.2. Public Header Parameter Names

people using JWEs can define extra Header Parameter names too 🌸 but to avoid collisions, any new one should either be registered in the IANA "JSON Web Signature and Encryption Header Parameters" registry set up by [JWS], or be a Public Name: a value that contains a Collision-Resistant Name. either way, the definer needs to take reasonable precautions to make sure they actually control the part of the namespace they're using to define the Header Parameter name 🫢

new Header Parameters should be introduced sparingly, because they can lead to non-interoperable JWEs 😭

4.3. Private Header Parameter Names

a producer and a consumer of a JWE can agree to use Header Parameter names that are Private Names: names that aren't Registered Header Parameter names (Section 4.1) or Public Header Parameter names (Section 4.2) πŸ”₯ unlike Public ones, Private Header Parameter names are subject to collision, so they should be used with caution, bestie 🫣

5. Producing and Consuming JWEs πŸ¦‹

5.1. Message Encryption ✨

okay so bestie, here's how encryption actually goes down πŸ” the order of these steps doesn't matter unless one step needs the output of another one πŸ’…

  1. Figure out the Key Management Mode used by the algorithm that picks the Content Encryption Key value. (That's the algorithm recorded in the alg (algorithm) Header Parameter of the resulting JWE πŸŽ€)
  2. When Key Wrapping, Key Encryption, or Key Agreement with Key Wrapping is happening, generate a random CEK value 🎲 RFC 4086 [RFC4086] has the considerations for making random values, so go read that. The CEK MUST have a length equal to what the content encryption algorithm needs πŸ”₯
  3. When Direct Key Agreement or Key Agreement with Key Wrapping is happening, use the key agreement algorithm to compute the agreed upon key 🀝 With Direct Key Agreement, the CEK is just the agreed upon key. With Key Agreement with Key Wrapping, the agreed upon key gets used to wrap the CEK 🎁
  4. When Key Wrapping, Key Encryption, or Key Agreement with Key Wrapping is happening, encrypt the CEK to the recipient. The result is the JWE Encrypted Key πŸ”‘
  5. When Direct Key Agreement or Direct Encryption is happening, the JWE Encrypted Key is the empty octet sequence 🫧
  6. When Direct Encryption is happening, the CEK is the shared symmetric key 🧚
  7. Compute the encoded key value BASE64URL(JWE Encrypted Key) πŸ“
  8. If the JWE JSON Serialization is being used, repeat this whole process (steps 1-7) for each recipient πŸ‘‘
  9. Generate a random JWE Initialization Vector of the correct size for the content encryption algorithm (if the algorithm needs one) 🌸 Otherwise, the JWE Initialization Vector is the empty octet sequence 🫧
  10. Compute the encoded Initialization Vector value BASE64URL(JWE Initialization Vector) πŸ’œ
  11. If a zip parameter was included, compress the plaintext with the compression algorithm you specified, and let M be the octet sequence for the compressed plaintext πŸ—œοΈ Otherwise, M is the octet sequence for the plaintext 🍰
  12. Build the JSON object(s) holding the Header Parameters you want, which together make up the JOSE Header ✨ That's one or more of the JWE Protected Header, the JWE Shared Unprotected Header, and the JWE Per-Recipient Unprotected Header πŸŽ€
  13. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE Protected Header)). If there's no JWE Protected Header (which can only happen with the JWE JSON Serialization when there's no protected member), this value is the empty string πŸ™ˆ
  14. Let the Additional Authenticated Data encryption parameter be ASCII(Encoded Protected Header). But if a JWE AAD value is there (which can only happen with the JWE JSON Serialization), the Additional Authenticated Data encryption parameter is instead ASCII(Encoded Protected Header || '.' || BASE64URL(JWE AAD)) 🫢
  15. Encrypt M with the CEK, the JWE Initialization Vector, and the Additional Authenticated Data value, using the content encryption algorithm you specified πŸ” This makes the JWE Ciphertext value and the JWE Authentication Tag (which is the Authentication Tag that comes out of the encryption operation) πŸ¦‹
  16. Compute the encoded ciphertext value BASE64URL(JWE Ciphertext) πŸ’…
  17. Compute the encoded Authentication Tag value BASE64URL(JWE Authentication Tag) πŸ’–
  18. If a JWE AAD value is present, compute the encoded AAD value BASE64URL(JWE AAD) 🧁
  19. Create the serialized output you want. The Compact Serialization of this result is the string below 🌈 The JWE JSON Serialization is described in Section 7.2 πŸ“–
BASE64URL(UTF8(JWE Protected Header)) || '.' ||
BASE64URL(JWE Encrypted Key) || '.' ||
BASE64URL(JWE Initialization Vector) || '.' ||
BASE64URL(JWE Ciphertext) || '.' ||
BASE64URL(JWE Authentication Tag)

5.2. Message Decryption πŸ•΅οΈβ€β™€οΈ

okay the decryption is basically encryption in reverse πŸ”„ Same deal: the order doesn't matter unless the steps depend on each other's outputs. And if any of these steps fail, the encrypted content can't be validated 🚫

when there are multiple recipients, it's the application's call which recipients' encrypted content has to successfully validate for the JWE to be accepted 🎭 Sometimes the encrypted content for every recipient has to validate, or the JWE is considered invalid. Other times, only one recipient's encrypted content needs to validate. But in every case, the encrypted content for at least one recipient MUST successfully validate, or the JWE MUST be considered invalid πŸ’€

  1. Parse the JWE representation to pull out the serialized values for its components 🧩 With the JWE Compact Serialization, those components are the base64url-encoded JWE Protected Header, JWE Encrypted Key, JWE Initialization Vector, JWE Ciphertext, and JWE Authentication Tag. With the JWE JSON Serialization, the components also include the base64url-encoded JWE AAD, plus the unencoded JWE Shared Unprotected Header and JWE Per-Recipient Unprotected Header values πŸŽ€ With the Compact Serialization, those five values come in that exact order, each one separated from the next by a single period (.) character, which means there are exactly four delimiting period characters πŸ“ The JWE JSON Serialization is described in Section 7.2 πŸ“–
  2. Base64url decode the encoded JWE Protected Header, JWE Encrypted Key, JWE Initialization Vector, JWE Ciphertext, JWE Authentication Tag, and JWE AAD 🫧 This only works if there are no line breaks, whitespace, or other extra characters in there πŸ™…β€β™€οΈ
  3. Check that the octets you got from decoding the encoded JWE Protected Header are a UTF-8-encoded representation of a completely valid JSON object that follows RFC 7159 [RFC7159]. That JSON object is now the JWE Protected Header πŸ’…
  4. If you're using the JWE Compact Serialization, the JOSE Header is just the JWE Protected Header. Otherwise, with the JWE JSON Serialization, the JOSE Header is the union of the members of the JWE Protected Header, the JWE Shared Unprotected Header, and the matching JWE Per-Recipient Unprotected Header. All of those have to be completely valid JSON objects 🧠 During this step, check that the resulting JOSE Header doesn't have any duplicate Header Parameter names 🚨 With the JWE JSON Serialization, that rule also means the same Header Parameter name MUST NOT show up in different JSON object values that together make up the JOSE Header 😭
  5. Check that the implementation understands and can process every field it's required to support, whether that's required by this specification, by the algorithms being used, or by the crit Header Parameter value. Also check that the values of those parameters are understood and supported πŸ”
  6. Figure out the Key Management Mode used by the algorithm specified by the alg (algorithm) Header Parameter πŸ—οΈ
  7. Check that the JWE uses a key the recipient knows about 🫢
  8. When Direct Key Agreement or Key Agreement with Key Wrapping is happening, use the key agreement algorithm to compute the agreed upon key 🀝 With Direct Key Agreement, the CEK is the agreed upon key. With Key Agreement with Key Wrapping, the agreed upon key gets used to decrypt the JWE Encrypted Key πŸ”“
  9. When Key Wrapping, Key Encryption, or Key Agreement with Key Wrapping is happening, decrypt the JWE Encrypted Key to get the CEK. The CEK MUST have a length equal to what the content encryption algorithm needs πŸ”₯ Also, when there are multiple recipients, each recipient can only decrypt the JWE Encrypted Key values that were encrypted to a key they actually have πŸ™ˆ So it's totally normal to only be able to decrypt one of the per-recipient JWE Encrypted Key values to get the CEK πŸ’β€β™€οΈ And see Section 11.5 for the security considerations on mitigating timing attacks 🚨⏱️
  10. When Direct Key Agreement or Direct Encryption is happening, check that the JWE Encrypted Key value is an empty octet sequence 🫧
  11. When Direct Encryption is happening, the CEK is the shared symmetric key 🧚
  12. Record whether the CEK could be successfully figured out for this recipient or not πŸ“
  13. If the JWE JSON Serialization is being used, repeat this process (steps 4-12) for each recipient in the representation πŸ‘‘
  14. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE Protected Header)). If there's no JWE Protected Header (which can only happen with the JWE JSON Serialization when there's no protected member), this value is the empty string πŸ™ˆ
  15. Let the Additional Authenticated Data encryption parameter be ASCII(Encoded Protected Header). But if a JWE AAD value is there (which can only happen with the JWE JSON Serialization), the Additional Authenticated Data encryption parameter is instead ASCII(Encoded Protected Header || '.' || BASE64URL(JWE AAD)) 🫢
  16. Decrypt the JWE Ciphertext using the CEK, the JWE Initialization Vector, the Additional Authenticated Data value, and the JWE Authentication Tag (which is the Authentication Tag that goes into the calculation), using the content encryption algorithm you specified πŸ” This returns the decrypted plaintext and validates the JWE Authentication Tag the way the algorithm specifies. If the JWE Authentication Tag is wrong, the input gets rejected and you don't emit any decrypted output at all πŸ™…β€β™€οΈπŸ’”
  17. If a zip parameter was included, uncompress the decrypted plaintext with the compression algorithm you specified πŸ—œοΈ
  18. If there wasn't a single recipient where all of the decryption steps succeeded, then the JWE MUST be considered invalid πŸ’€ Otherwise, output the plaintext πŸŽ‰ In the JWE JSON Serialization case, also return a result to the application saying which recipients the decryption succeeded for and which it failed for πŸ“‹

Finally, the application gets to decide which algorithms can be used in a given context πŸ‘‘ Even if a JWE decrypts successfully, unless the algorithms used in the JWE are acceptable to the application, it SHOULD consider the JWE to be invalid 🚫 bestie, that's a whole vibe check 🫠

5.3. String Comparison Rules πŸ”€

the string comparison rules for this spec are the same ones defined in Section 5.3 of [JWS] πŸ’–

6. Key Identification πŸ”‘

okay so the key identification methods here are the exact same ones from Section 6 of [JWS] ✨, with one twist: the key being identified is the public key that the JWE was encrypted to πŸ’–

7. Serializations πŸŽ€

okay bestie, JWEs come in two flavors: the JWE Compact Serialization or the JWE JSON Serialization πŸ’… Applications using this spec need to decide which serialization they're using, plus which serialization features they want. Like, an app might say "we only do the JWE JSON Serialization," or "we only support one recipient," or "we support multiple recipients" πŸ¦‹ And the good news? JWE implementations only need to build the features their app actually needs. No extra homework 🫢

7.1. JWE Compact Serialization πŸ’–

The JWE Compact Serialization is the compact, URL-safe version of encrypted content 🌸 The whole string looks like this:

BASE64URL(UTF8(JWE Protected Header)) || '.' ||
BASE64URL(JWE Encrypted Key) || '.' ||
BASE64URL(JWE Initialization Vector) || '.' ||
BASE64URL(JWE Ciphertext) || '.' ||
BASE64URL(JWE Authentication Tag)

Only one recipient is supported here πŸ™ˆ and there's no syntax for the JWE Shared Unprotected Header, the JWE Per-Recipient Unprotected Header, or JWE AAD values. Not me having to live with that limitation 😭

7.2. JWE JSON Serialization πŸ¦‹

The JWE JSON Serialization represents encrypted content as a JSON object πŸ’… It's not optimized for compactness and it's not URL safe, so it's more of a "give me all the details" kind of vibe ✨

There are two closely related syntaxes here. One is the fully general syntax, which lets you encrypt content to more than one recipient πŸ‘‘ The other is the flattened syntax, which is built for the single-recipient case 🧚

7.2.1. General JWE JSON Serialization Syntax 🌸

These members are defined for the top-level JSON objects used in the fully general JWE JSON Serialization syntax:

  • protected: The "protected" member MUST be present and contain the value BASE64URL(UTF8(JWE Protected Header)) when the JWE Protected Header value is non-empty; otherwise, it MUST be absent. These Header Parameter values are integrity protected πŸ”’
  • unprotected: The "unprotected" member MUST be present and contain the value JWE Shared Unprotected Header when the JWE Shared Unprotected Header value is non-empty; otherwise, it MUST be absent. This value is an unencoded JSON object, NOT a string πŸ™…β€β™€οΈ These Header Parameter values are not integrity protected.
  • iv: The "iv" member MUST be present and contain the value BASE64URL(JWE Initialization Vector) when the JWE Initialization Vector value is non-empty; otherwise, it MUST be absent.
  • aad: The "aad" member MUST be present and contain the value BASE64URL(JWE AAD)) when the JWE AAD value is non-empty; otherwise, it MUST be absent. A JWE AAD value can be included to supply a base64url-encoded value that's integrity protected but not encrypted 🫢
  • ciphertext: The "ciphertext" member MUST be present and contain the value BASE64URL(JWE Ciphertext).
  • tag: The "tag" member MUST be present and contain the value BASE64URL(JWE Authentication Tag) when the JWE Authentication Tag value is non-empty; otherwise, it MUST be absent.
  • recipients: The "recipients" member value MUST be an array of JSON objects. Each object holds info for a single recipient. This member MUST be present with exactly one array element per recipient, even if some or all of those element values are the empty JSON object "{}". That can happen when all Header Parameter values are shared between all recipients, and when no encrypted key is used, like when doing Direct Encryption πŸ’œ

The following members are defined for use in the JSON objects that are elements of the "recipients" array:

  • header: The "header" member MUST be present and contain the value JWE Per-Recipient Unprotected Header when the JWE Per-Recipient Unprotected Header value is non-empty; otherwise, it MUST be absent. This value is an unencoded JSON object, NOT a string. These Header Parameter values are not integrity protected.
  • encrypted_key: The "encrypted_key" member MUST be present and contain the value BASE64URL(JWE Encrypted Key) when the JWE Encrypted Key value is non-empty; otherwise, it MUST be absent.

At least one of the "header", "protected", and "unprotected" members MUST be present so that "alg" and "enc" Header Parameter values are conveyed for each recipient computation πŸ”₯

Additional members can be present in both of the JSON objects above. If an implementation doesn't understand them, they MUST be ignored πŸ™ˆ

Some Header Parameters, including the "alg" parameter, can be shared among all recipient computations. Header Parameters in the JWE Protected Header and JWE Shared Unprotected Header values are shared among all recipients ✨

The Header Parameter values used when creating or validating per-recipient ciphertext and Authentication Tag values are the union of three sets of Header Parameter values that may be present:

  1. the JWE Protected Header, represented in the "protected" member,
  2. the JWE Shared Unprotected Header, represented in the "unprotected" member, and
  3. the JWE Per-Recipient Unprotected Header, represented in the "header" member of the recipient's array element.

The union of these sets of Header Parameters comprises the JOSE Header. The Header Parameter names in the three locations MUST be disjoint πŸ’…

Each JWE Encrypted Key value is computed using the parameters of the corresponding JOSE Header value, the same way as for the JWE Compact Serialization. This has the desirable property that each JWE Encrypted Key value in the "recipients" array is identical to the value that would have been computed for the same parameter in the JWE Compact Serialization πŸ¦‹ Likewise, the JWE Ciphertext and JWE Authentication Tag values match those produced for the JWE Compact Serialization, as long as the JWE Protected Header value (which represents the integrity-protected Header Parameter values) matches the one used in the JWE Compact Serialization 🌸

All recipients use the same JWE Protected Header, JWE Initialization Vector, JWE Ciphertext, and JWE Authentication Tag values (when present). That means potentially big space savings if the message is large πŸ“ So all Header Parameters that specify how the plaintext is treated MUST be the same for all recipients. Mainly, this means the "enc" (encryption algorithm) Header Parameter value in the JOSE Header for each recipient, plus any parameters of that algorithm, MUST be the same πŸ’œ

Here's the summary of what a JWE using the general JWE JSON Serialization looks like:

{
 "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>"
}

Check out Appendix A.4 for an example JWE using the general JWE JSON Serialization syntax πŸ‘€

7.2.2. Flattened JWE JSON Serialization Syntax 🧚

The flattened JWE JSON Serialization syntax is based on the general syntax, just flattened, so it's optimized for the single-recipient case ✨ It removes the "recipients" member and instead puts the members that would live in the "recipients" array (the "header" and "encrypted_key" members) right in the top-level JSON object, at the same level as the "ciphertext" member πŸŽ€

The "recipients" member MUST NOT be present when using this syntax. Other than that syntax difference, JWE JSON Serialization objects using the flattened syntax are processed exactly the same as those using the general syntax πŸ’–

Here's the summary of a JWE using the 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>"
}

Note that with the flattened syntax, just like the general syntax, any unprotected Header Parameter values can live in the "unprotected" member, the "header" member, or both 🫢

Check out Appendix A.5 for an example JWE using the flattened JWE JSON Serialization syntax 🌈

8. TLS Requirements πŸ”’

The Transport Layer Security (TLS) requirements for this spec are the same as the ones in Section 8 of [JWS] πŸ’…

9. Distinguishing between JWS and JWE Objects πŸ‘‘

There are a few ways to tell whether an object is a JWS or a JWE πŸ•΅οΈβ€β™€οΈ All of these methods give the same result for every legal input value. They might give different results for malformed inputs though, so watch out πŸ™ˆ

  • If the object uses the JWS Compact Serialization or the JWE Compact Serialization, you can count the base64url-encoded segments separated by period ('.') characters. The count differs for JWSs and JWEs. JWSs have three segments separated by two period ('.') characters. JWEs have five segments separated by four period ('.') characters πŸ¦‹
  • If the object uses the JWS JSON Serialization or the JWE JSON Serialization, the members used will be different. JWSs have a "payload" member and JWEs do not. JWEs have a "ciphertext" member and JWSs do not 🌸
  • The JOSE Header for a JWS can be told apart from the JOSE Header for a JWE by checking the "alg" (algorithm) Header Parameter value. If the value represents a digital signature or MAC algorithm, or is the value "none", it's for a JWS. If it represents a Key Encryption, Key Wrapping, Direct Key Agreement, Key Agreement with Key Wrapping, or Direct Encryption algorithm, it's for a JWE. (Pulling out the "alg" value is straightforward with the JWS Compact Serialization or the JWE Compact Serialization, and can be trickier with the JWS JSON Serialization or the JWE JSON Serialization 🧐)
  • The JOSE Header for a JWS can also be told apart from the JOSE Header for a JWE by checking whether an "enc" (encryption algorithm) member exists. If the "enc" member exists, it's a JWE. Otherwise, it's a JWS πŸ’œ

10. IANA Considerations 🌈

10.1. JSON Web Signature and Encryption Header Parameters Registration πŸ’œ

This section registers the Header Parameter names defined in Section 4.1 in the IANA "JSON Web Signature and Encryption Header Parameters" registry, which was established by [JWS] ✨

10.1.1. Registry Contents πŸ“‹

okay so this is the actual list of header parameters that go into the registry, and every single one is for JWE πŸ’– each entry has a name, a description, where it's allowed to show up (always JWE here), who controls changes (the IESG, every time), and which section of RFC 7516 defines it

Header Parameter Name: "alg"
Header Parameter Description: Algorithm
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.1 of RFC 7516

Header Parameter Name: "enc"
Header Parameter Description: Encryption Algorithm
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.2 of RFC 7516

Header Parameter Name: "zip"
Header Parameter Description: Compression Algorithm
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.3 of RFC 7516
Header Parameter Name: "jku"
Header Parameter Description: JWK Set URL
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.4 of RFC 7516

Header Parameter Name: "jwk"
Header Parameter Description: JSON Web Key
Header Parameter Usage Location(s): JWE

Change Controller: IESG
Specification Document(s): Section 4.1.5 of RFC 7516

Header Parameter Name: "kid"
Header Parameter Description: Key ID
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.6 of RFC 7516

Header Parameter Name: "x5u"
Header Parameter Description: X.509 URL
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.7 of RFC 7516

Header Parameter Name: "x5c"
Header Parameter Description: X.509 Certificate Chain
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.8 of RFC 7516

Header Parameter Name: "x5t"
Header Parameter Description: X.509 Certificate SHA-1 Thumbprint
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.9 of RFC 7516

Header Parameter Name: "x5t#S256"
Header Parameter Description: X.509 Certificate SHA-256 Thumbprint
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.10 of RFC 7516

Header Parameter Name: "typ"
Header Parameter Description: Type
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.11 of RFC 7516
Header Parameter Name: "cty"
Header Parameter Description: Content Type
Header Parameter Usage Location(s): JWE
Change Controller: IESG
Specification Document(s): Section 4.1.12 of RFC 7516

Header Parameter Name: "crit"
Header Parameter Description: Critical
Header Parameter Usage Location(s): JWE

Change Controller: IESG
Specification Document(s): Section 4.1.13 of RFC 7516

11. Security Considerations πŸ›‘οΈ

okay this part is SERIOUS bestie 😭 every security issue that matters for any cryptographic app has to be dealt with by the JWS/JWE/JWK agents, and that includes protecting the user's asymmetric private keys and symmetric secret keys, plus having countermeasures for all the different attacks out there

all the security considerations from the JWS spec also apply here πŸ” and all the security considerations from XML Encryption 1.1 [W3C.REC-xmlenc-core1-20130411] also apply too, except the ones that are only about XML

11.1. Key Entropy and Random Values 🎲

go check Section 10.1 of [JWS] for the security stuff on key entropy and random values πŸ’… on top of the uses listed there, random values are also used for Content Encryption Keys (CEKs) and Initialization Vectors (IVs) when you're doing encryption, so don't forget those!!

11.2. Key Protection πŸ”‘

check Section 10.2 of [JWS] for key protection info. on top of the keys listed there that need protecting, anyone doing encryption has to protect the key encryption key AND the Content Encryption Key. like, if the key encryption key gets compromised, every bit of content protected with that key could get disclosed 😭 and if the CEK gets compromised, the encrypted content tied to it could get disclosed too

11.3. Using Matching Algorithm Strengths πŸ’ͺ

algorithms with matching strengths should be used together whenever possible, no cap 🧁 for example, if you're using AES Key Wrap with a certain key size, you should go with the same key size when you use AES GCM too. and if the key encryption and content encryption algorithms are different, the effective security is set by the weaker one of the two πŸ₯€

also see RFC 3766 [RFC3766] for how to figure out the strength of public keys used for exchanging symmetric keys

11.4. Adaptive Chosen-Ciphertext Attacks πŸ‘€

when you're decrypting, be super careful not to let the JWE recipient become an oracle for decrypting messages πŸ™ˆ RFC 3218 [RFC3218] should be consulted for specific countermeasures against attacks on RSAES-PKCS1-v1_5. an attacker could change the "alg" Header Parameter from "RSA-OAEP" to "RSA1_5" to cause a formatting error that can be detected and used to recover the CEK, even if RSAES-OAEP was used to encrypt the CEK πŸ’€ so it's really important to report ALL formatting errors to the CEK, Additional Authenticated Data, or ciphertext as a single error when the encrypted content gets rejected

this kind of attack can also be stopped by restricting a key to a limited set of algorithms, usually just one πŸ”’ for instance, if the key is marked as being for "RSA-OAEP" only, any attempt to decrypt a message with the "RSA1_5" algorithm using that key should fail immediately because the key is being used wrong

11.5. Timing Attacks ⏱️

to mitigate the attacks described in RFC 3218 [RFC3218], the recipient MUST NOT distinguish between format, padding, and length errors of encrypted keys 🚫 it's also strongly recommended that, if an improperly formatted key comes in, the recipient substitutes a randomly generated CEK and moves on to the next step, to help mitigate timing attacks ✨

12. References πŸ“š

12.1. Normative References

[JWA]      Jones, M., "JSON Web Algorithms (JWA)", RFC 7518,
           DOI 10.17487/RFC7518, May 2015,
           <http://www.rfc-editor.org/info/rfc7518>.

[JWK]      Jones, M., "JSON Web Key (JWK)", RFC 7517,
           DOI 10.17487/RFC7517, May 2015,
           <http://www.rfc-editor.org/info/rfc7517>.

[JWS]      Jones, M., Bradley, J., and N. Sakimura, "JSON Web
           Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May
           2015, <http://www.rfc-editor.org/info/rfc7515>.

[RFC1951]  Deutsch, P., "DEFLATE Compressed Data Format Specification
           version 1.3", RFC 1951, DOI 10.17487/RFC1951, May 1996,
           <http://www.rfc-editor.org/info/rfc1951>.

[RFC20]    Cerf, V., "ASCII format for Network Interchange", STD 80,
           RFC 20, DOI 10.17487/RFC0020, October 1969,
           <http://www.rfc-editor.org/info/rfc20>.

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119,
           DOI 10.17487/RFC2119, March 1997,
           <http://www.rfc-editor.org/info/rfc2119>.

[RFC3629]  Yergeau, F., "UTF-8, a transformation format of ISO
           10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November
           2003, <http://www.rfc-editor.org/info/rfc3629>.

[RFC4949]  Shirey, R., "Internet Security Glossary, Version 2",
           FYI 36, RFC 4949, DOI 10.17487/RFC4949, August 2007,
           <http://www.rfc-editor.org/info/rfc4949>.

[RFC5280]  Cooper, D., Santesson, S., Farrell, S., Boeyen, S.,
           Housley, R., and W. Polk, "Internet X.509 Public Key
           Infrastructure Certificate and Certificate Revocation List
           (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008,
           <http://www.rfc-editor.org/info/rfc5280>.

[RFC7159]  Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
           Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March
           2014, <http://www.rfc-editor.org/info/rfc7159>.

[UNICODE]  The Unicode Consortium, "The Unicode Standard",
           <http://www.unicode.org/versions/latest/>.

12.2. Informative References

[AES]      National Institute of Standards and Technology (NIST),
           "Advanced Encryption Standard (AES)", FIPS PUB 197,
           November 2001, <http://csrc.nist.gov/publications/
           fips/fips197/fips-197.pdf>.

[JSE]      Bradley, J. and N. Sakimura (editor), "JSON Simple
           Encryption", September 2010,
           <http://jsonenc.info/enc/1.0/>.

[JSMS]     Rescorla, E. and J. Hildebrand, "JavaScript Message
           Security Format", Work in Progress,
           draft-rescorla-jsms-00, March 2011.

[NIST.800-38D]
           National Institute of Standards and Technology (NIST),
           "Recommendation for Block Cipher Modes of Operation:
           Galois/Counter Mode (GCM) and GMAC", NIST PUB 800-38D,
           November 2007, <http://csrc.nist.gov/publications/
           nistpubs/800-38D/SP-800-38D.pdf>.

[RFC3218]  Rescorla, E., "Preventing the Million Message Attack on
           Cryptographic Message Syntax", RFC 3218,
           DOI 10.17487/RFC3218, January 2002,
           <http://www.rfc-editor.org/info/rfc3218>.

[RFC3447]  Jonsson, J. and B. Kaliski, "Public-Key Cryptography
           Standards (PKCS) #1: RSA Cryptography Specifications
           Version 2.1", RFC 3447, DOI 10.17487/RFC3447, February
           2003, <http://www.rfc-editor.org/info/rfc3447>.

[RFC3766]  Orman, H. and P. Hoffman, "Determining Strengths For
           Public Keys Used For Exchanging Symmetric Keys", BCP 86,
           RFC 3766, DOI 10.17487/RFC3766, April 2004,
           <http://www.rfc-editor.org/info/rfc3766>.

[RFC4086]  Eastlake 3rd, D., Schiller, J., and S. Crocker,
           "Randomness Requirements for Security", BCP 106, RFC 4086,
           DOI 10.17487/RFC4086, June 2005,
           <http://www.rfc-editor.org/info/rfc4086>.

[RFC5652]  Housley, R., "Cryptographic Message Syntax (CMS)", STD 70,
           RFC 5652, DOI 10.17487/RFC5652, September 2009,
           <http://www.rfc-editor.org/info/rfc5652>.

[W3C.REC-xmlenc-core1-20130411]
           Eastlake, D., Reagle, J., Hirsch, F., and T. Roessler,
           "XML Encryption Syntax and Processing Version 1.1", World
           Wide Web Consortium Recommendation
           REC-xmlenc-core1-20130411, April 2013,
           <http://www.w3.org/TR/2013/REC-xmlenc-core1-20130411/>.

Appendix A. JWE Examples ✨

this section has examples of JWE computations 🧚

A.1. Example JWE using RSAES-OAEP and AES GCM πŸ’–

this example encrypts the plaintext "The true sign of intelligence is not knowledge but imagination." for the recipient, using RSAES-OAEP for key encryption and AES GCM for content encryption πŸ¦‹ the plaintext, written out as a JSON array, looks like this:

[84, 104, 101, 32, 116, 114, 117, 101, 32, 115, 105, 103, 110, 32,
111, 102, 32, 105, 110, 116, 101, 108, 108, 105, 103, 101, 110, 99,
101, 32, 105, 115, 32, 110, 111, 116, 32, 107, 110, 111, 119, 108,
101, 100, 103, 101, 32, 98, 117, 116, 32, 105, 109, 97, 103, 105,
110, 97, 116, 105, 111, 110, 46]

A.1.1. JOSE Header πŸŽ€

Okay so this example JWE Protected Header is giving clear instructions, bestie πŸ’… It declares that:

  • The Content Encryption Key is encrypted to the recipient using the RSAES-OAEP algorithm to produce the JWE Encrypted Key. πŸ”
  • Authenticated encryption is performed on the plaintext using the AES GCM algorithm with a 256-bit key to produce the ciphertext and the Authentication Tag. ✨
{"alg":"RSA-OAEP","enc":"A256GCM"}

Encoding this JWE Protected Header as BASE64URL(UTF8(JWE Protected Header)) gives this value:

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ

A.1.2. Content Encryption Key (CEK) πŸ—οΈ

Generate a 256-bit random CEK. In this example, the value (using JSON array notation) is:

[177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154,
212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122,
234, 64, 252]

A.1.3. Key Encryption πŸ”‘

Encrypt the CEK with the recipient's public key using the RSAES-OAEP algorithm to produce the JWE Encrypted Key. This example uses the RSA key represented in JSON Web Key [JWK] format below (with line breaks within values for display purposes only): πŸ₯Ή

{"kty":"RSA",
 "n":"oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW
      cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S
      psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a
      sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS
      tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj
      YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw",
 "e":"AQAB",
 "d":"kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N
      WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9
      3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk
      qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl
      t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd
      VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ",
 "p":"1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ-
      SWxkbkmoEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lf
      fNn03IXqWF5MDFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0",
 "q":"wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBm
      UDdaDYVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aX
      IWxKwd4gvxFImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc",
 "dp":"ZK-YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KL
      hMXvo-uz-KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827
      rnpZzAJKpdhWAgqrXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE",
 "dq":"Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCj
      ywcMlYYg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDB
      UfCAiJVeESOjJDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis",
 "qi":"VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8-ZW1FxU7
      AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E3
      eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY"
}

The resulting JWE Encrypted Key value is:

[56, 163, 154, 192, 58, 53, 222, 4, 105, 218, 136, 218, 29, 94, 203,
22, 150, 92, 129, 94, 211, 232, 53, 89, 41, 60, 138, 56, 196, 216,
82, 98, 168, 76, 37, 73, 70, 7, 36, 8, 191, 100, 136, 196, 244, 220,
145, 158, 138, 155, 4, 117, 141, 230, 199, 247, 173, 45, 182, 214,
74, 177, 107, 211, 153, 11, 205, 196, 171, 226, 162, 128, 171, 182,
13, 237, 239, 99, 193, 4, 91, 219, 121, 223, 107, 167, 61, 119, 228,
173, 156, 137, 134, 200, 80, 219, 74, 253, 56, 185, 91, 177, 34, 158,
89, 154, 205, 96, 55, 18, 138, 43, 96, 218, 215, 128, 124, 75, 138,
243, 85, 25, 109, 117, 140, 26, 155, 249, 67, 167, 149, 231, 100, 6,
41, 65, 214, 251, 232, 87, 72, 40, 182, 149, 154, 168, 31, 193, 126,
215, 89, 28, 111, 219, 125, 182, 139, 235, 195, 197, 23, 234, 55, 58,
63, 180, 68, 202, 206, 149, 75, 205, 248, 176, 67, 39, 178, 60, 98,
193, 32, 238, 122, 96, 158, 222, 57, 183, 111, 210, 55, 188, 215,
206, 180, 166, 150, 166, 106, 250, 55, 229, 72, 40, 69, 214, 216,
104, 23, 40, 135, 212, 28, 127, 41, 80, 175, 174, 168, 115, 171, 197,
89, 116, 92, 103, 246, 83, 216, 182, 176, 84, 37, 147, 35, 45, 219,
172, 99, 226, 233, 73, 37, 124, 42, 72, 49, 242, 35, 127, 184, 134,
117, 114, 135, 206]

Encoding this JWE Encrypted Key as BASE64URL(JWE Encrypted Key) gives this value (with line breaks for display purposes only):

OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGe
ipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDb
Sv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaV
mqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je8
1860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi
6UklfCpIMfIjf7iGdXKHzg

A.1.4. Initialization Vector 🌸

Generate a random 96-bit JWE Initialization Vector. In this example, the value is:

[227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219]

Encoding this JWE Initialization Vector as BASE64URL(JWE Initialization Vector) gives this value:

48V1_ALb6US04U3b

A.1.5. Additional Authenticated Data 🧩

Let the Additional Authenticated Data encryption parameter be ASCII(BASE64URL(UTF8(JWE Protected Header))). This value is:

[101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 48, 69,
116, 84, 48, 70, 70, 85, 67, 73, 115, 73, 109, 86, 117, 89, 121, 73,
54, 73, 107, 69, 121, 78, 84, 90, 72, 81, 48, 48, 105, 102, 81]

A.1.6. Content Encryption πŸ”’

Perform authenticated encryption on the plaintext with the AES GCM algorithm using the CEK as the encryption key, the JWE Initialization Vector, and the Additional Authenticated Data value above, requesting a 128-bit Authentication Tag output. The resulting ciphertext is:

[229, 236, 166, 241, 53, 191, 115, 196, 174, 43, 73, 109, 39, 122,
233, 96, 140, 206, 120, 52, 51, 237, 48, 11, 190, 219, 186, 80, 111,
104, 50, 142, 47, 167, 59, 61, 181, 127, 196, 21, 40, 82, 242, 32,
123, 143, 168, 226, 73, 216, 176, 144, 138, 247, 106, 60, 16, 205,
160, 109, 64, 63, 192]

The resulting Authentication Tag value is:

[92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91,
210, 145]

Encoding this JWE Ciphertext as BASE64URL(JWE Ciphertext) gives this value (with line breaks for display purposes only):

5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6ji
SdiwkIr3ajwQzaBtQD_A

Encoding this JWE Authentication Tag as BASE64URL(JWE Authentication Tag) gives this value:

XFBoMYUZodetZdvTiFvSkQ

A.1.7. Complete Representation 🎁

Assemble the final representation: The Compact Serialization of this result is the string BASE64URL(UTF8(JWE Protected Header)) || '.' || BASE64URL(JWE Encrypted Key) || '.' || BASE64URL(JWE Initialization Vector) || '.' || BASE64URL(JWE Ciphertext) || '.' || BASE64URL(JWE Authentication Tag).

The final result in this example (with line breaks for display purposes only) is:

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.
OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGe
ipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDb
Sv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaV
mqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je8
1860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi
6UklfCpIMfIjf7iGdXKHzg.
48V1_ALb6US04U3b.
5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6ji
SdiwkIr3ajwQzaBtQD_A.
XFBoMYUZodetZdvTiFvSkQ

A.1.8. Validation βœ…

This example illustrates the process of creating a JWE with RSAES-OAEP for key encryption and AES GCM for content encryption. These results can be used to validate JWE decryption implementations for these algorithms. Note that since the RSAES-OAEP computation includes random values, the encryption results above will not be completely reproducible. However, since the AES GCM computation is deterministic, the JWE Encrypted Ciphertext values will be the same for all encryptions performed using these inputs. πŸ’–

A.2. Example JWE using RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256 🌈

This example encrypts the plaintext "Live long and prosper." to the recipient using RSAES-PKCS1-v1_5 for key encryption and AES_128_CBC_HMAC_SHA_256 for content encryption. The representation of this plaintext (using JSON array notation) is: πŸ––

[76, 105, 118, 101, 32, 108, 111, 110, 103, 32, 97, 110, 100, 32,
112, 114, 111, 115, 112, 101, 114, 46]

A.2.1. JOSE Header πŸ‘‘

The following example JWE Protected Header declares that:

  • The Content Encryption Key is encrypted to the recipient using the RSAES-PKCS1-v1_5 algorithm to produce the JWE Encrypted Key. 🫢
  • Authenticated encryption is performed on the plaintext using the AES_128_CBC_HMAC_SHA_256 algorithm to produce the ciphertext and the Authentication Tag. πŸ¦‹
{"alg":"RSA1_5","enc":"A128CBC-HS256"}

Encoding this JWE Protected Header as BASE64URL(UTF8(JWE Protected Header)) gives this value:

eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0

A.2.2. Content Encryption Key (CEK) πŸ’œ

Generate a 256-bit random CEK. In this example, the key value is:

[4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106,
206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156,
44, 207]

A.2.3. Key Encryption ✨

Okay bestie, time to lock the CEK inside a box πŸ”. We encrypt it with the recipient's public key using RSAES-PKCS1-v1_5 to get the JWE Encrypted Key πŸ’–. This example uses the RSA key in JSON Web Key [JWK] format below (line breaks are just for display, btw πŸ™ˆ):

{"kty":"RSA",
 "n":"sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl
      UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre
      cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_
      7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI
      Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU
      7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw",
 "e":"AQAB",
 "d":"VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq
      1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry
      nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_
      0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj
      -VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj
      T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ",
 "p":"9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68
      ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEP
      krdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM",
 "q":"uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-y
      BhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN
      -3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0",
 "dp":"w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuv
       ngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcra
       Hawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs",
 "dq":"o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff
       7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_
       odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU",
 "qi":"eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC
       tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ
       B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo"
}

The resulting JWE Encrypted Key value is:

[80, 104, 72, 58, 11, 130, 236, 139, 132, 189, 255, 205, 61, 86, 151,
176, 99, 40, 44, 233, 176, 189, 205, 70, 202, 169, 72, 40, 226, 181,
156, 223, 120, 156, 115, 232, 150, 209, 145, 133, 104, 112, 237, 156,
116, 250, 65, 102, 212, 210, 103, 240, 177, 61, 93, 40, 71, 231, 223,
226, 240, 157, 15, 31, 150, 89, 200, 215, 198, 203, 108, 70, 117, 66,
212, 238, 193, 205, 23, 161, 169, 218, 243, 203, 128, 214, 127, 253,
215, 139, 43, 17, 135, 103, 179, 220, 28, 2, 212, 206, 131, 158, 128,
66, 62, 240, 78, 186, 141, 125, 132, 227, 60, 137, 43, 31, 152, 199,
54, 72, 34, 212, 115, 11, 152, 101, 70, 42, 219, 233, 142, 66, 151,
250, 126, 146, 141, 216, 190, 73, 50, 177, 146, 5, 52, 247, 28, 197,
21, 59, 170, 247, 181, 89, 131, 241, 169, 182, 246, 99, 15, 36, 102,
166, 182, 172, 197, 136, 230, 120, 60, 58, 219, 243, 149, 94, 222,
150, 154, 194, 110, 227, 225, 112, 39, 89, 233, 112, 207, 211, 241,
124, 174, 69, 221, 179, 107, 196, 225, 127, 167, 112, 226, 12, 242,
16, 24, 28, 120, 182, 244, 213, 244, 153, 194, 162, 69, 160, 244,
248, 63, 165, 141, 4, 207, 249, 193, 79, 131, 0, 169, 233, 127, 167,
101, 151, 125, 56, 112, 111, 248, 29, 232, 90, 29, 147, 110, 169,
146, 114, 165, 204, 71, 136, 41, 252]

Encoding this JWE Encrypted Key as BASE64URL(JWE Encrypted Key) gives this value (line breaks for display only, obvi πŸ’…):

UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm
1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7Pc
HALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIF
NPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8
rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv
-B3oWh2TbqmScqXMR4gp_A

A.2.4. Initialization Vector 🧸

Time to make a random 128-bit JWE Initialization Vector πŸŽ€. In this example, the value is:

[3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104,
101]

Encoding this JWE Initialization Vector as BASE64URL(JWE Initialization Vector) gives this value:

AxY8DCtDaGlsbGljb3RoZQ

A.2.5. Additional Authenticated Data 🌸

Let the Additional Authenticated Data encryption parameter be ASCII(BASE64URL(UTF8(JWE Protected Header))). This value is:

[101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 48, 69,
120, 88, 122, 85, 105, 76, 67, 74, 108, 98, 109, 77, 105, 79, 105,
74, 66, 77, 84, 73, 52, 81, 48, 74, 68, 76, 85, 104, 84, 77, 106, 85,
50, 73, 110, 48]

A.2.6. Content Encryption πŸ”₯

Now we do the authenticated encryption on the plaintext with the AES_128_CBC_HMAC_SHA_256 algorithm. We use the CEK as the encryption key, plus the JWE Initialization Vector and the Additional Authenticated Data value from above. The steps for doing this with the values from Appendix A.3 are detailed in Appendix B 🧚. The resulting ciphertext is:

[40, 57, 83, 181, 119, 33, 133, 148, 198, 185, 243, 24, 152, 230, 6,
75, 129, 223, 127, 19, 210, 82, 183, 230, 168, 33, 215, 104, 143,
112, 56, 102]

The resulting Authentication Tag value is:

[246, 17, 244, 190, 4, 95, 98, 3, 231, 0, 115, 157, 242, 203, 100,
191]

Encoding this JWE Ciphertext as BASE64URL(JWE Ciphertext) gives this value:

KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY

Encoding this JWE Authentication Tag as BASE64URL(JWE Authentication Tag) gives this value:

9hH0vgRfYgPnAHOd8stkvw

A.2.7. Complete Representation πŸ¦‹

Time to assemble the final representation 🧩. The Compact Serialization of this result is the string below:

BASE64URL(UTF8(JWE Protected Header)) || '.' ||
BASE64URL(JWE Encrypted Key) || '.' || BASE64URL(JWE Initialization
Vector) || '.' || BASE64URL(JWE Ciphertext) || '.' || BASE64URL(JWE
Authentication Tag)

The final result in this example (line breaks for display purposes only) is:

eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.
UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm
1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7Pc
HALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIF
NPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8
rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv
-B3oWh2TbqmScqXMR4gp_A.
AxY8DCtDaGlsbGljb3RoZQ.
KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.
9hH0vgRfYgPnAHOd8stkvw

A.2.8. Validation πŸ’œ

This example shows how to make a JWE with RSAES-PKCS1-v1_5 for key encryption and AES_CBC_HMAC_SHA2 for content encryption. These results can be used to validate JWE decryption implementations for these algorithms πŸ’…. Heads up: since the RSAES-PKCS1-v1_5 computation includes random values, the encryption results above will not be completely reproducible πŸ™ˆ. However, since the AES-CBC computation is deterministic, the JWE Encrypted Ciphertext values will be the same for all encryptions performed using these inputs ✨.

A.3. Example JWE Using AES Key Wrap and AES_128_CBC_HMAC_SHA_256 🌈

This example encrypts the plaintext "Live long and prosper." for the recipient, using AES Key Wrap for key encryption and AES_128_CBC_HMAC_SHA_256 for content encryption. The representation of this plaintext (using JSON array notation) is:

[76, 105, 118, 101, 32, 108, 111, 110, 103, 32, 97, 110, 100, 32,
112, 114, 111, 115, 112, 101, 114, 46]

A.3.1. JOSE Header πŸ“

The following example JWE Protected Header declares that:

  • The Content Encryption Key is encrypted to the recipient using the AES Key Wrap algorithm with a 128-bit key to produce the JWE Encrypted Key.
  • Authenticated encryption is performed on the plaintext using the AES_128_CBC_HMAC_SHA_256 algorithm to produce the ciphertext and the Authentication Tag.
{"alg":"A128KW","enc":"A128CBC-HS256"}

Encoding this JWE Protected Header as BASE64URL(UTF8(JWE Protected Header)) gives this value:

eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0

A.3.2. Content Encryption Key (CEK) πŸ”‘

Generate a 256-bit random CEK. In this example, the value is:

[4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106,
206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156,
44, 207]

A.3.3. Key Encryption πŸŽ€

Encrypt the CEK with the shared symmetric key using the AES Key Wrap algorithm to produce the JWE Encrypted Key. This example uses the symmetric key in JSON Web Key [JWK] format below:

{"kty":"oct",
 "k":"GawgguFyGrWKav7AX4VKUg"
}

The resulting JWE Encrypted Key value is:

[232, 160, 123, 211, 183, 76, 245, 132, 200, 128, 123, 75, 190, 216,
22, 67, 201, 138, 193, 186, 9, 91, 122, 31, 246, 90, 28, 139, 57, 3,
76, 124, 193, 11, 98, 37, 173, 61, 104, 57]

Encoding this JWE Encrypted Key as BASE64URL(JWE Encrypted Key) gives this value:

6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ

A.3.4. Initialization Vector 🧸

Generate a random 128-bit JWE Initialization Vector. In this example, the value is:

[3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104,
101]

Encoding this JWE Initialization Vector as BASE64URL(JWE Initialization Vector) gives this value:

AxY8DCtDaGlsbGljb3RoZQ

A.3.5. Additional Authenticated Data 🌸

Let the Additional Authenticated Data encryption parameter be ASCII(BASE64URL(UTF8(JWE Protected Header))). This value is:

[101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 66, 77, 84, 73, 52,
83, 49, 99, 105, 76, 67, 74, 108, 98, 109, 77, 105, 79, 105, 74, 66,
77, 84, 73, 52, 81, 48, 74, 68, 76, 85, 104, 84, 77, 106, 85, 50, 73,
110, 48]

A.3.6. Content Encryption πŸ”₯

Do the authenticated encryption on the plaintext with the AES_128_CBC_HMAC_SHA_256 algorithm, using the CEK as the encryption key, the JWE Initialization Vector, and the Additional Authenticated Data value from above. The steps for doing this with the values from this example are detailed in Appendix B 🧚. The resulting ciphertext is:

[40, 57, 83, 181, 119, 33, 133, 148, 198, 185, 243, 24, 152, 230, 6,
75, 129, 223, 127, 19, 210, 82, 183, 230, 168, 33, 215, 104, 143,
112, 56, 102]

The resulting Authentication Tag value is:

[83, 73, 191, 98, 104, 205, 211, 128, 201, 189, 199, 133, 32, 38,
194, 85]

Encoding this JWE Ciphertext as BASE64URL(JWE Ciphertext) gives this value:

KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY

Encoding this JWE Authentication Tag as BASE64URL(JWE Authentication Tag) gives this value:

U0m_YmjN04DJvceFICbCVQ

A.3.7. Complete Representation πŸ¦‹

Time to assemble the final representation 🧩. The Compact Serialization of this result is the string below:

BASE64URL(UTF8(JWE Protected Header)) || '.' ||
BASE64URL(JWE Encrypted Key) || '.' || BASE64URL(JWE Initialization
Vector) || '.' || BASE64URL(JWE Ciphertext) || '.' || BASE64URL(JWE
Authentication Tag)

The final result in this example (line breaks for display purposes only) is:

eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.
6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ.
AxY8DCtDaGlsbGljb3RoZQ.
KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.
U0m_YmjN04DJvceFICbCVQ

A.3.8. Validation

okay so this example is the whole vibe πŸŽ€ It creates a JWE using AES Key Wrap for the key encryption and AES GCM for the content encryption. Your decryption code can check itself against these results, bestie πŸ’… Both AES Key Wrap and AES GCM are deterministic, so you get the same JWE value every single time you use these inputs ✨ That means you can also use it to check your encryption code, because the computation is totally reproducible 🫢

A.4. Example JWE Using General JWE JSON Serialization

This section has an example using the general JWE JSON Serialization syntax πŸ¦‹ It shows how you can encrypt the same plaintext to multiple recipients at once, which is so iconic πŸ‘‘

There are two recipients in this example. The first recipient uses the same algorithm and key as Appendix A.2, and the second uses the same algorithm and key as Appendix A.3. Because of that, the resulting JWE Encrypted Key values come out the same, so we're not going to redo those computations here πŸ’–

The plaintext, the CEK, the JWE Initialization Vector, and the JWE Protected Header are shared by all the recipients 🌸 This has to be the case, since the ciphertext and the Authentication Tag are shared too 🧚

A.4.1. JWE Per-Recipient Unprotected Headers

The first recipient uses the RSAES-PKCS1-v1_5 algorithm to encrypt the CEK ✨ The second one uses AES Key Wrap to encrypt the CEK 🌈 Both keys come with key ID values. The two JWE Per-Recipient Unprotected Header values for these algorithms and key IDs are:

{"alg":"RSA1_5","kid":"2011-04-29"}

and

{"alg":"A128KW","kid":"7"}

A.4.2. JWE Protected Header

Authenticated encryption happens on the plaintext using the AES_128_CBC_HMAC_SHA_256 algorithm πŸ”₯ That gives us the shared JWE Ciphertext and JWE Authentication Tag values. The JWE Protected Header value for this is:

{"enc":"A128CBC-HS256"}

Encode this JWE Protected Header as BASE64URL(UTF8(JWE Protected Header)) and you get this value:

eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0

A.4.3. JWE Shared Unprotected Header

This JWE uses the "jku" Header Parameter to point at a JWK Set πŸ“ In the JWE Shared Unprotected Header, it's written like this:

{"jku":"https://server.example.com/keys.jwks"}

A.4.4. Complete JOSE Header Values

Put the JWE Per-Recipient Unprotected Header, the JWE Protected Header, and the JWE Shared Unprotected Header together, and you get the JOSE Header values for the first and second recipients, in that order πŸŽ€

{"alg":"RSA1_5",
 "kid":"2011-04-29",
 "enc":"A128CBC-HS256",
 "jku":"https://server.example.com/keys.jwks"}

and

{"alg":"A128KW",
 "kid":"7",
 "enc":"A128CBC-HS256",
 "jku":"https://server.example.com/keys.jwks"}

A.4.5. Additional Authenticated Data

Let the Additional Authenticated Data encryption parameter be ASCII(BASE64URL(UTF8(JWE Protected Header))) πŸ¦‹ Here's the value:

[101, 121, 74, 108, 98, 109, 77, 105, 79, 105, 74, 66, 77, 84, 73,
52, 81, 48, 74, 68, 76, 85, 104, 84, 77, 106, 85, 50, 73, 110, 48]

A.4.6. Content Encryption

Now we do authenticated encryption on the plaintext with the AES_128_CBC_HMAC_SHA_256 algorithm πŸ’… We use the CEK as the encryption key, plus the JWE Initialization Vector and the Additional Authenticated Data value from above. If you want the step-by-step using the values from Appendix A.3, check out Appendix B 🧚 The resulting ciphertext is:

[40, 57, 83, 181, 119, 33, 133, 148, 198, 185, 243, 24, 152, 230, 6,
75, 129, 223, 127, 19, 210, 82, 183, 230, 168, 33, 215, 104, 143,
112, 56, 102]

The resulting Authentication Tag value is:

[51, 63, 149, 60, 252, 148, 225, 25, 92, 185, 139, 245, 35, 2, 47,
207]

Encode this JWE Ciphertext as BASE64URL(JWE Ciphertext) and you get:

KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY

Encode this JWE Authentication Tag as BASE64URL(JWE Authentication Tag) and you get:

Mz-VPPyU4RlcuYv1IwIvzw

A.4.7. Complete JWE JSON Serialization Representation

Here's the full JWE JSON Serialization for all of these values 🌷 The line breaks inside the values are just there so it's easier to read πŸ™ˆ

{
 "protected":
  "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0",
 "unprotected":
  {"jku":"https://server.example.com/keys.jwks"},
 "recipients":[
  {"header":
    {"alg":"RSA1_5","kid":"2011-04-29"},
   "encrypted_key":
    "UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-
     kFm1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKx
     GHZ7PcHALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3
     YvkkysZIFNPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPh
     cCdZ6XDP0_F8rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPg
     wCp6X-nZZd9OHBv-B3oWh2TbqmScqXMR4gp_A"},
  {"header":
    {"alg":"A128KW","kid":"7"},
   "encrypted_key":
    "6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ"}],
 "iv":
  "AxY8DCtDaGlsbGljb3RoZQ",
 "ciphertext":
  "KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY",
 "tag":
  "Mz-VPPyU4RlcuYv1IwIvzw"
}

A.5. Example JWE Using Flattened JWE JSON Serialization

This section has an example of the flattened JWE JSON Serialization syntax 🧁 It shows how to encrypt the plaintext to a single recipient inside a flattened JSON structure, which is a nice little glow-up for simple cases 🌈

The values here are the same as the ones for the second recipient in the previous example, Appendix A.4 ✨

The full JWE JSON Serialization for these values is below. The line breaks inside the values are for display only 🫢

{
 "protected":
  "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0",
 "unprotected":
  {"jku":"https://server.example.com/keys.jwks"},
 "header":
  {"alg":"A128KW","kid":"7"},
 "encrypted_key":
  "6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ",
 "iv":
  "AxY8DCtDaGlsbGljb3RoZQ",
 "ciphertext":
  "KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY",
 "tag":
  "Mz-VPPyU4RlcuYv1IwIvzw"
}

Appendix B. Example AES_128_CBC_HMAC_SHA_256 Computation

This appendix walks through the AES_128_CBC_HMAC_SHA_256 authenticated encryption, using the values from the example in Appendix A.3 πŸ” As described where this algorithm is defined in Sections 5.2 and 5.2.3 of JWA, the AES_CBC_HMAC_SHA2 family uses Advanced Encryption Standard (AES) in Cipher Block Chaining (CBC) mode with Public-Key Cryptography Standards (PKCS) #7 padding for the encryption πŸ’œ For the integrity part, it uses an HMAC SHA-2 function, and in this case that's HMAC SHA-256 πŸ¦‹

B.1. Extract MAC_KEY and ENC_KEY from Key

The 256 bit AES_128_CBC_HMAC_SHA_256 key K used in this example is, in JSON array notation:

[4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106,
206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156,
44, 207]

Use the first 128 bits of this key as the HMAC SHA-256 key MAC_KEY, which is:

[4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106,
206]

Use the last 128 bits of this key as the AES-CBC key ENC_KEY, which is:

[107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156, 44,
207]

Quick heads-up πŸ‘€ the MAC key comes before the encryption key in the input key K. That's the opposite order from the algorithm names in the identifiers "AES_128_CBC_HMAC_SHA_256" and "A128CBC-HS256", so don't mix them up πŸ’€

B.2. Encrypt Plaintext to Create Ciphertext

Encrypt the plaintext with AES in CBC mode, using PKCS #7 padding and the ENC_KEY from above 🧚 The plaintext in this example is:

[76, 105, 118, 101, 32, 108, 111, 110, 103, 32, 97, 110, 100, 32,
112, 114, 111, 115, 112, 101, 114, 46]

The encryption result is below, and it's the ciphertext output πŸ“

[40, 57, 83, 181, 119, 33, 133, 148, 198, 185, 243, 24, 152, 230, 6,
75, 129, 223, 127, 19, 210, 82, 183, 230, 168, 33, 215, 104, 143,
112, 56, 102]

B.3. 64-Bit Big-Endian Representation of AAD Length

The Additional Authenticated Data (AAD) in this example is:

[101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 66, 77, 84, 73, 52,
83, 49, 99, 105, 76, 67, 74, 108, 98, 109, 77, 105, 79, 105, 74, 66,
77, 84, 73, 52, 81, 48, 74, 68, 76, 85, 104, 84, 77, 106, 85, 50, 73,
110, 48]

This AAD is 51-bytes long, which is 408-bits long πŸŽ€ The octet string AL, which is the number of bits in AAD written as a big-endian 64-bit unsigned integer, is:

[0, 0, 0, 0, 0, 0, 1, 152]

B.4. Initialization Vector Value

The Initialization Vector value used in this example is:

[3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104,
101]

B.5. Create Input to HMAC Computation

Concatenate the AAD, the Initialization Vector, the ciphertext, and the AL value 🧩 The result of that concatenation is:

[101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 66, 77, 84, 73, 52,
83, 49, 99, 105, 76, 67, 74, 108, 98, 109, 77, 105, 79, 105, 74, 66,
77, 84, 73, 52, 81, 48, 74, 68, 76, 85, 104, 84, 77, 106, 85, 50, 73,
110, 48, 3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111,
116, 104, 101, 40, 57, 83, 181, 119, 33, 133, 148, 198, 185, 243, 24,
152, 230, 6, 75, 129, 223, 127, 19, 210, 82, 183, 230, 168, 33, 215,
104, 143, 112, 56, 102, 0, 0, 0, 0, 0, 0, 1, 152]

B.6. Compute HMAC Value

Compute the HMAC SHA-256 of the concatenated value above πŸ”₯ This result, M, is:

[83, 73, 191, 98, 104, 205, 211, 128, 201, 189, 199, 133, 32, 38,
194, 85, 9, 84, 229, 201, 219, 135, 44, 252, 145, 102, 179, 140, 105,
86, 229, 116]

B.7. Truncate HMAC Value to Create Authentication Tag

Use the first half (128 bits) of the HMAC output M as the Authentication Tag output T πŸ¦‹ This truncated value is:

[83, 73, 191, 98, 104, 205, 211, 128, 201, 189, 199, 133, 32, 38,
194, 85]

Acknowledgements ✨

okay bestie, the people who made this spec happen 🫢 "JSON Simple Encryption" [JSE] and "JavaScript Message Security Format" [JSMS] both lowkey shaped this doc, like they were the main characters 🌸 This spec tries to reuse as many concepts as it can from XML Encryption 1.1 [W3C.REC-xmlenc-core1-20130411] and RFC 5652 [RFC5652], but with simple, compact JSON-based data structures. no cap, that's the whole vibe πŸ’…

Special thanks to John Bradley, Eric Rescorla, and Nat Sakimura for the discussions that helped shape the content πŸ’– Thanks also to Eric Rescorla and Joe Hildebrand for letting this document reuse text from [JSMS], and to Eric Rescorla for co-authoring many drafts. he really showed up πŸ‘‘

Thanks to Axel Nennker, Emmanuel Raviart, Brian Campbell, and Edmund Jay for validating the examples in this specification 🧚 the examples are literally right because of them ✨

This specification is the work of the JOSE working group, which has dozens of active and dedicated participants 🌈 The following individuals contributed ideas, feedback, and wording that influenced this specification, and they are absolutely iconic πŸŽ€

Richard Barnes, John Bradley, Brian Campbell, Alissa Cooper, Breno de Medeiros, Stephen Farrell, Dick Hardt, Jeff Hodges, Russ Housley, Edmund Jay, Scott Kelly, Stephen Kent, Barry Leiba, James Manger, Matt Miller, Kathleen Moriarty, Tony Nadalin, Hideki Nara, Axel Nennker, Ray Polk, Emmanuel Raviart, Eric Rescorla, Pete Resnick, Nat Sakimura, Jim Schaad, Hannes Tschofenig, and Sean Turner πŸ¦‹

Jim Schaad and Karen O'Donoghue chaired the JOSE working group πŸ“ and Sean Turner, Stephen Farrell, and Kathleen Moriarty served as Security Area Directors during the creation of this specification. the management team was giving stability πŸ’œ


Authors' Addresses πŸŽ€

Michael B. Jones πŸ’– Microsoft

EMail: mbj@microsoft.com URI: http://self-issued.info/

Joe Hildebrand 🌸 Cisco Systems, Inc.

EMail: jhildebr@cisco.com

and that's the whole spec, bestie 🌈✨ thanks for reading with me πŸ«ΆπŸ’…

πŸ“¦ where this page comes from