step crypto jwe – encrypt and decrypt data and keys using JSON Web Encryption (JWE)


step crypto jwe subcommand [arguments] [global-flags] [subcommand-flags]


The step crypto jwe command group provides facilities for encrypting and decrypting content and representing encrypted content using JSON-based data structures as defined by the JSON Web Encryption (JWE) specification in RFC7516, using algorithms defined in the JSON Web Algorithms (JWA) specification in RFC7518. A JWE is a data structure representing an encrypted and integrity-protected message.

There are two JWE serializations: the compact serialization is a small, URL- safe representation that base64 encodes the JWE components. The compact serialization is a URL-safe string, suitable for space-constrained environments such as HTTP headers and URI query parameters. The JSON serialization represents JWEs as JSON objects and allows the same content to be encrypted to multiple parties (using multiple keys).

A typical JWE in compact serialization is a dot-separated string with five parts:

* Header: metadata describing how the plaintext payload was processed to
  produce ciphertext (e.g., which algorithms were used to encrypt the
  content encryption key and the plaintext payload)

* Encrypted Key: the "content encryption key" that was used to encrypt the
  plaintext payload, encrypted for the JWE recipient(s) (see: "what's with
  the encrypted key" below)

* Initialization Vector: an initialization vector for use with the specified
  encryption algorithm, if applicable

* Ciphertext: the ciphertext value resulting produced from authenticated
  encryption of the plaintext with additional authenticated data

* Authentication Tag: value resulting fromthe authenticated encryption of
  the plaintext with additional authenticated data

What’s with encrypted key?

This is somewhat confusing. Instead of directly encrypting the plaintext payload, JWE typically generates a new “content encryption key” then encrypts that key for the intended recipient(s).

While versatile, JWE is easy to use incorrectly. Therefore, any use of this subcommand requires the use of the ‘–subtle’ flag as a misuse prevention mechanism. You should only use this subcommand if you know what you’re doing. If possible, you’re better off using the higher level ‘crypto nacl’ command group.


This example demonstrates how to produce a JWE for a recipient using the RSA-OAEP algorithm to encrypt the content encryption key (producing the encrypted key), and the A256GCM (AES GCM with 256-bit key) algorithm to produce the ciphertext and authentication tag.

1. Encode the JWE header with the desired "alg" and "enc" members then
   encode it producing the *header*
     =` eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ

2. Generate a random content encryption key (CEK), encrypt it using
   RSA-OAEP, producing the *encrypted key*

3. Generate a random initialization vector

4. Perform authenticated encryption over the plaintext using the content
   encryption key and A256GCM algorithm with the base64-encoded JWE headers
   provided as additional authenticated data producing the *ciphertext* and
   *authentication tag*

5. Assemble the final result (compact serialization) to produce the string:

      BASE64URL(UTF8(header)) || '.'
   || BASE64URL(encrypted key) || '.'
   || BASE64URL(initialization vector) || '.'
   || BASE64URL(ciphertext) || '.'
   || BASE64URL(authentication tag)

   Producing a result like (line breaks for display purposes only):


Create a JWK for encryption use:

$ step crypto jwk create --use enc p256.enc.priv

Encrypt a message using the previous public key (output indented for display purposes):

$ echo The message | step crypto jwe encrypt --key

Decrypt the previous message using the private key:

$ step crypto jwe decrypt --key p256.enc.priv < message.json
Please enter the password to decrypt p256.enc.priv: ********
The message

Encrypt a message using a shared password:

$ echo The message | step crypto jwe encrypt --alg PBES2-HS256+A128KW
Please enter the password to encrypt the content encryption key: ********

Decrypt a message protected with shared password:

$ step crypto jwe decrypt < message.json
Please enter the password to decrypt the content encryption key: ********
The message


encryptencrypt a payload using JSON Web Encryption (JWE)
decryptverify a JWE and decrypt ciphertext