Skip to content
Daniel edited this page Feb 26, 2018 · 15 revisions

Contents

Primer

A JSON Web Encryption (JWE) represents encrypted content. It provides confidentiality and optionally integrity protection for this content JWE consists of:

  1. A JSON-based header
  2. An encrypted content encryption key
  3. An initialization vector
  4. Some additional authenticated data
  5. The ciphertext
  6. An authentication tag

To understand a JWE, it is good to understand the way it encrypts its payload.

As you may have noticed, a JWE contains two encrypted parts. The encrypted content encryption key and the ciphertext. When you construct a JWE, you have to provide the public key of the JWE’s recipient. During initialization, a shared content encryption key is created. The provided payload is then encrypted using this key, yielding the ciphertext. The shared content encryption key is then encrypted using the recipient’s public key and included in the JWE.

The recipient can use his matching private key to decrypt the encrypted content encryption key. Using this decrypted key he can decrypt the ciphertext and read the JWE payload.

Click here for a visualization of the JWE encryption and decryption flow.
  Provided By You         Computed Internally                     JWE                               Recipient


 +-------------+                                            +---------------+                                +-------------+
 |             |                                            |               |                                |             |
 |   Payload   +------------------^------------------------->  Ciphertext   +---------------------------^----+   Payload   |
 |             |                  |                         |               |                           |    |             |
 +-------------+                  |                         +---------------+                           |    +-------------+
                         encrypts |                                                            decrypts |
                                  |                                                                     |
                                  |                                                                     |
                    +-------------+--------------+     +----------------------------+     +-------------+--------------+
                    |                            |     |                            |     |                            |
                    |           Shared           +--^-->         Encrypted          +--^-->           Shared           |
                    |   Content Encryption Key   |  |  |   Content Encryption Key   |  |  |   Content Encryption Key   |
                    |                            |  |  |                            |  |  |                            |
                    +----------------------------+  |  +----------------------------+  |  +----------------------------+
                                                    |                                  |
                                                    |                                  |
                                                    |                                  |
+----------------+              encrypts            |                                  |  decrypts  +-----------------+
|                |                                  |                                  |            |                 |
|   Public Key   +----------------------------------+                                  +------------+   Private Key   |
|                |                                                                                  |                 |
+----------------+                                                                                  +-----------------+

Don’t worry though, most of this logic and the associated values are constructed under the hood. You’ll not have to worry about them too much. Nonetheless, they are described in more detail in the following sections.

Header

The JWE Header is a JSON object specifying the encryption algorithms applied to the payload and the content encryption key. Optionally it can contain additional properties of the JWE.

Example

The following header specifies two algorithms. The JWE’s payload is encrypted using the AES_256_CBC_HMAC_SHA_512 algorithm, yielding the ciphertext. The shared key, with which this payload encryption is performed is encrypted using the RSAES-PKCS1-v1_5 algorithm and included in the JWE.

{ "alg": "RSA1_5", "enc": "A256CBC-HS512" }

A detailed list describing possible header parameters can be found here.

Content Encryption Key

The payload is encrypted using a shared content encryption key that is randomly generated when initializing a JWE. The recipient of the JWE has to know this key so that he or she can decrypt the ciphertext. This means that this content encryption key has to be encrypted as well and included in the JWE.

The public key used to encrypt this shared content encryption key has to be provided by you. The recipient can use the matching private key to decrypt the content encryption key and subsequently the ciphertext, yielding the payload.

Initialization Vector

If the content encryption algorithm uses an initialization vector, it’s value is included in the JWE. If it does not use an initialization vector, the value is empty.

Additional Authenticated Data

An additional value that is integrity protected by the authenticated encryption operation. Since JOSESwift only implements compact serialization, the JWE header is used as additional authenticated data. This means that the header is not encrypted but integrity protected.

Ciphertext

The ciphertext resulting from the authenticated encryption of the plaintext and the additional authenticated data.

Authentication Tag

The output of the authenticated encryption that ensures the integrity of the ciphertext and the additional authenticated data. If the encryption algorithm does not use an authentication tag, the value is empty.

Serialization

JOSESwift implements compact serialization for JWE. Compact serialization represents a JWE as the following concatenation:

base64url(header) + "." +
base64url(encrypted content encryption key) + "." +
base64url(initialization vector) + "." +
base64url(ciphertext) + "." +
base64url(authentication tag) + "." +

Note that the additional authenticated data is not explicitly included in the compact serialization. This is because the header is used as additional authenticated data.

Example

Given the following header and payload:

// Header
{ "alg": "RSA1_5", "enc": "A256CBC-HS512" }

// Payload
"Trumpets of Mexico 🏜"

We get the following values, encoded as base64url:

// base64url(header)
eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIn0

// base64url(encrypted content encryption key)
b5Zbb...NglvQ

// base64url(initialization vector)
3vgaWb4EQbk_W1PHiBZBlg

// base64url(ciphertext)
5Hjsko9pPFpmkaNDLBYj9fUZp52FGVIpJo-jdAut3wk

// base64url(authentication tag)
hZXvBYxZEV4x7ACGhx3ky5pzNuf1X6UsmI3iEcYjHmM

Which yields the following compact serialization (with line breaks added for readability):

eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIn0.
b5Zbb...NglvQ.
3vgaWb4EQbk_W1PHiBZBlg.
5Hjsko9pPFpmkaNDLBYj9fUZp52FGVIpJo-jdAut3wk.
hZXvBYxZEV4x7ACGhx3ky5pzNuf1X6UsmI3iEcYjHmM
Clone this wiki locally