RFC 7516
JSON Web Encryption (JWE)
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 Notice βοΈ
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 π
- 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 π) - 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 π₯
- 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 π
- 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 π
- When Direct Key Agreement or Direct Encryption is happening, the JWE Encrypted Key is the empty octet sequence π«§
- When Direct Encryption is happening, the CEK is the shared symmetric key π§
- Compute the encoded key value
BASE64URL(JWE Encrypted Key)π - If the JWE JSON Serialization is being used, repeat this whole process (steps 1-7) for each recipient π
- 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 π«§
- Compute the encoded Initialization Vector value
BASE64URL(JWE Initialization Vector)π - If a
zipparameter 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 π° - 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 π
- 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 noprotectedmember), this value is the empty string π - 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 insteadASCII(Encoded Protected Header || '.' || BASE64URL(JWE AAD))π«Ά - 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) π¦
- Compute the encoded ciphertext value
BASE64URL(JWE Ciphertext)π - Compute the encoded Authentication Tag value
BASE64URL(JWE Authentication Tag)π - If a JWE AAD value is present, compute the encoded AAD value
BASE64URL(JWE AAD)π§ - 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 π
- 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 π - 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 π ββοΈ
- 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 π
- 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 π
- 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
critHeader Parameter value. Also check that the values of those parameters are understood and supported π - Figure out the Key Management Mode used by the algorithm specified by the
alg(algorithm) Header Parameter ποΈ - Check that the JWE uses a key the recipient knows about π«Ά
- 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 π
- 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 π¨β±οΈ
- When Direct Key Agreement or Direct Encryption is happening, check that the JWE Encrypted Key value is an empty octet sequence π«§
- When Direct Encryption is happening, the CEK is the shared symmetric key π§
- Record whether the CEK could be successfully figured out for this recipient or not π
- If the JWE JSON Serialization is being used, repeat this process (steps 4-12) for each recipient in the representation π
- 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 noprotectedmember), this value is the empty string π - 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 insteadASCII(Encoded Protected Header || '.' || BASE64URL(JWE AAD))π«Ά - 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 π ββοΈπ
- If a
zipparameter was included, uncompress the decrypted plaintext with the compression algorithm you specified ποΈ - 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 valueBASE64URL(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:
- the JWE Protected Header, represented in the "protected" member,
- the JWE Shared Unprotected Header, represented in the "unprotected" member, and
- 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
- ietf: rfc7516 2015-05
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms