Skip to main content

Proposed Refactoring of JOSE to Align Encryption and Key Wrapping
draft-barnes-jose-key-wrapping-00

The information below is for an old version of the document.
Document Type
This is an older version of an Internet-Draft whose latest revision state is "Expired".
Author Richard Barnes
Last updated 2013-04-03
RFC stream (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-barnes-jose-key-wrapping-00
JOSE Working Group                                             R. Barnes
Internet-Draft                                                       BBN
Intended status: Informational                            April 03, 2013
Expires: October 5, 2013

   Proposed Refactoring of JOSE to Align Encryption and Key Wrapping
                   draft-barnes-jose-key-wrapping-00

Abstract

   The discussions around key wrapping in the JOSE working group have
   raised new requirements for wrapped keys, namely: (1) Wrapping keys
   other than symmetric keys, (2) cryptographically binding attributes
   to keys, and (3) allowing the use of AEAD cryptographic algorithms
   for key wrapping (other than AES-KW).  This document proposes a
   refactoring of the JOSE document set that provides a cleaner
   conceptual structure for JWS / JWE and transparent support for
   wrapped keys, all with a relatively minor impact on the compact form
   of JWS and JWE objects.

Status of this Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at http://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on October 5, 2013.

Copyright Notice

   Copyright (c) 2013 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents
   (http://trustee.ietf.org/license-info) in effect on the date of
   publication of this document.  Please review these documents
   carefully, as they describe your rights and restrictions with respect

Barnes                   Expires October 5, 2013                [Page 1]
Internet-Draft                JOSE Refactor                   April 2013

   to this document.  Code Components extracted from this document must
   include Simplified BSD License text as described in Section 4.e of
   the Trust Legal Provisions and are provided without warranty as
   described in the Simplified BSD License.

Table of Contents

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
   2.  Requirements . . . . . . . . . . . . . . . . . . . . . . . . .  5
   3.  Proposed Changes . . . . . . . . . . . . . . . . . . . . . . .  6
   4.  Summary of Benefits / Costs  . . . . . . . . . . . . . . . . .  7
   5.  Example: Current vs. Proposed  . . . . . . . . . . . . . . . .  8
     5.1.  AES-GCM with AES-KW wrapping . . . . . . . . . . . . . . .  8
     5.2.  AES-GCM with AES-GCM wrapping  . . . . . . . . . . . . . . 10
   6.  Rationale  . . . . . . . . . . . . . . . . . . . . . . . . . . 12
     6.1.  Requirements and Goals . . . . . . . . . . . . . . . . . . 12
     6.2.  JWE vs Key Wrapping  . . . . . . . . . . . . . . . . . . . 12
     6.3.  JWE with Wrapped Keys  . . . . . . . . . . . . . . . . . . 14
     6.4.  Impact on the Compact Format . . . . . . . . . . . . . . . 16
     6.5.  JWS  . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
     6.6.  Summary  . . . . . . . . . . . . . . . . . . . . . . . . . 18
   7.  Revised JSON Format and Translation to Compact . . . . . . . . 19
     7.1.  Translation from JSON to Compact . . . . . . . . . . . . . 19
     7.2.  Translation from Compact to JSON . . . . . . . . . . . . . 20
   8.  Disposition of Header Fields (Proposal Part 3) . . . . . . . . 22
   9.  Key Wrapping Procedure (Proposal Part 4) . . . . . . . . . . . 24
     9.1.  Wrapping procedure . . . . . . . . . . . . . . . . . . . . 24
     9.2.  Unwrapping Procedure . . . . . . . . . . . . . . . . . . . 25
   10. Compact JWK Marshaling (Proposal Part 4) . . . . . . . . . . . 26
     10.1. JWKS2  . . . . . . . . . . . . . . . . . . . . . . . . . . 26
     10.2. JWKS3  . . . . . . . . . . . . . . . . . . . . . . . . . . 27
     10.3. Test Cases . . . . . . . . . . . . . . . . . . . . . . . . 28
     10.4. Performance on Test Cases  . . . . . . . . . . . . . . . . 29
   11. Security Considerations  . . . . . . . . . . . . . . . . . . . 30
   12. IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 31
   13. Normative References . . . . . . . . . . . . . . . . . . . . . 32
   Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 33

Barnes                   Expires October 5, 2013                [Page 2]
Internet-Draft                JOSE Refactor                   April 2013

1.  Introduction

   The goal of a JOSE object is to provide the recipient with the result
   of a cryptographic operation (encryption or signature) and
   instructions for how to process that result.  These instructutions
   are in two main parts: (1) A cryptographic algorithm to be applied,
   and (2) the key to be used with that algorithm (in wrapped form).

   The current structure of the JWE and JWS headers scatters these two
   information elements across several different header parameters.  For
   example, if an object has been encrypted with the "direct" mode of
   key agreement, then the recipient must reconstruct the algorithm from
   the "enc", "epu", and "epv" parameters.  If a developer wants to
   validate that a JOSE algorithm has all required parameters for a
   given algorithm, he must search through all header fields.

   It would help clarify the structure of JOSE objects if algorithm
   parameters and key parameters could be grouped together.  We propose
   to make two changes to the JWE and JWS headers:

   1.  Re-define the "alg" parameter to contain all necessary parameters
       to describe the encryption algorithm.

   2.  Define a new "key" parameter to contain all necessary paramters
       to describe the CMK.

   This restructuring also simplifies key wrapping, by using JWE for key
   wrapping.  Since the encrypted CMK is just another encrypted object,
   and because the wrapped key is encapsulated in the "key" object, it
   can re-use the "alg" and "enc" fields - making the encrypted key just
   another JWE.  The following example shows how the proposed
   refactoring changes the implicit grouping of key-related fields in
   JWE into an explicit grouping.

   Current:  {"enc":"A128CBC+HS256",       "alg":"RSA1_5","kid":"1" }
   Proposed: {"alg":"A128CBC+HS256","key":{"alg":"RSA1_5","key":"1"}}

                                 Figure 1

   This example JWE has three fields, "enc", "alg", and "kid".  One of
   these fields relates to how the content of the JWE itself is
   encrypted; the other two relate to how the key is encrypted.  The
   proposed syntax groups the key-related fields together into a JSON
   object.  In fact, this new object can be thought of a second JWE,
   encrypting the key instead of the content.

   This change has a minimal impact on the JWE and JWS compact
   serializations, both in terms of representation and processing.  In

Barnes                   Expires October 5, 2013                [Page 3]
Internet-Draft                JOSE Refactor                   April 2013

   the example above, the proposed header has the same information
   content as the original header, and is only 8 octets longer.  For
   JWE, the proposed form even offers a simplification in processing,
   since the encrypted key can be processed with the same code as the
   encrypted content - both are JWEs.

   The proposed form also allows for a much cleaner JSON representation
   than is currently allowed.  The following figure illustrates the
   current and proposed JSON serializations.  The proposed serialization
   is much more developer friendly, since it exposes header information
   directly, instead of in a base64-encoded string.

   Current:
   {
       "recipients": [{
           "header": "....",
           "encrypted_key": "...".
           "integrity_value": "..."
       }],
       "initialization_vector": "...",
       "ciphertext": "..."
   }

   Proposed:
   {
       "alg": {
           "name": "A128CBC+HS256",
           "iv": "..."
       },
       "key": {
           "alg":"RSA1_5",
           "key":"1"
           "data": "..."
       }
       "data": "...",
       "mac": "..."
   }

                                 Figure 2

   The remainder of this document describes the rational for the
   proposed changes in more detail, and provides an outline of the
   detailed changes that would be needed to implement the proposal.

Barnes                   Expires October 5, 2013                [Page 4]
Internet-Draft                JOSE Refactor                   April 2013

2.  Requirements

   o  Enable key wrapping with JWE

   o  Avoid having more than one format for the same key wrapped with
      the same algorithm

   o  Enable key wrapping with all AEAD algorithms, for JWE as well as
      external wrapped keys

   o  Enable password-based encryption for JWE

Barnes                   Expires October 5, 2013                [Page 5]
Internet-Draft                JOSE Refactor                   April 2013

3.  Proposed Changes

   o  JWE/JWS: Define required "alg" and "key" parameters

      *  "alg": JWA algorithm object

      *  "key": Key identifier or JWE containing encrypted key

   o  JWE/JWS: Define a revised JSON serialization and mapping to the
      compact serialization

   o  JWA: Refactor to describe algorithm objects for JWE/JWS

      *  Move algorithm parameters from JWE to JWA

      *  Define validation rules per algorithm (which parameters are
         required)

      *  Add password-based encryption parameters

   o  JWK: Define a procedure for using JWE to wrap keys

      *  OPTIONAL: Define a compact serialization for keys

   Details of these proposals are described below.

Barnes                   Expires October 5, 2013                [Page 6]
Internet-Draft                JOSE Refactor                   April 2013

4.  Summary of Benefits / Costs

   o  Costs:

      *  Few (<30) bytes of extra header overhead

      *  Breaks compatibility with old code

   o  Benefits:

      *  Clean architecture covering JWE, JWS, wrapped JWK

      *  Code re-use bewteen JWE processing and wrapped key processing

      *  Easier validation rules for algorithm parameters

      *  Key wrapping based on JWE in all cases

      *  Support for new use cases in compact serialization

      *  Key management for MAC

Barnes                   Expires October 5, 2013                [Page 7]
Internet-Draft                JOSE Refactor                   April 2013

5.  Example: Current vs. Proposed

   In this section, we consider two examples of how the proposed
   serialization offers cleaner syntax and more flexibility than the
   current structure.  First, we look at a JWE encrypted with AES-GCM,
   using a key wrapped with AES-KW.  This allows us to directly compare
   the two formats.  Second, we consider the same JWE, but using a key
   that is also protected with AES-GCM.  This case is easily supported
   in the proposed syntax, but impossible to support in the current
   syntax.  In both cases, the parties have a pre-shared key with
   identifier "preSharedKey".

5.1.  AES-GCM with AES-KW wrapping

   To create an an object encrypted with AES-GCM and AES-KW, we need to
   specify the following parameters:

   o  Algorithm name (A128GCM)

   o  Key wrapping algorithm (AES-KW)

   o  Key wrapping key ID ("preSharedKey")

   o  96-bit initialization vector

   o  Wrapped key

   o  Ciphertext

   o  Integrity check value

   In the current compact form, the header encodes the first three of
   these, and the remainder are appended as base64url-encoded
   components.

   CURRENT-COMPACT-HEADER:
   {"enc":"A128GCM","alg":"A128KW","kid":"preSharedKey"}

   CURRENT-COMPACT:
   eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiQTEyOEtXIiwia2lkIjoicHJlU2h
   hcmVkS2V5In0K
   .Pe15h6BYJ7SrEq0ev8m9ce4vq4phLFJK
   .hRskpf3RwFQmEKQ5
   .jZpHMF7GhBNYSD5QIJkBXWu6POh_KTN5
   .b2ersuWujfIaoghd5kOpWw

                                 Figure 3

Barnes                   Expires October 5, 2013                [Page 8]
Internet-Draft                JOSE Refactor                   April 2013

   In the proposed compact form, the header would have the same
   information, but arranged so that the key-wrapping parameters ("alg",
   "kid") are gathered under a "key" parameter.  The remaining
   components are appended in the same way.

   PROPOSED-COMPACT-HEADER:
   {"alg":"A128GCM",
    "key":{"alg":"A128KW","key":"preSharedKey"}}

   PROPOSED-COMPACT
   eyJhbGciOiJBMTI4R0NNIiwia2V5Ijp7ImFsZyI6IkExMjhLVyIsImtleSI
   6InByZVNoYXJlZEtleSJ9fQo
   .Pe15h6BYJ7SrEq0ev8m9ce4vq4phLFJK
   .hRskpf3RwFQmEKQ5
   .jZpHMF7GhBNYSD5QIJkBXWu6POh_KTN5
   .b2ersuWujfIaoghd5kOpWw

                                 Figure 4

   The proposed compact form of this JWE object is 189 octets long,
   while the current form is 178.  So the overhead imposed by the
   refactoring is 11 octets, or 6%.

   The difference is clearer with regard to the JSON representations.
   The current JSON form is just as opaque as the compact form.  By
   contrast, the proposed JSON form provides the header information
   without base64-encoding, making it more easily accessible.  The UTF-8
   serialization of the proposed JSON syntax is also 27% shorter than
   the serialization of the current JSON syntax (209 vs. 287 octets).

   CURRENT-JSON:
   {
       "recipients": [{
           "header": "eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiQTEyOEtX
                      Iiwia2lkIjoicHJlU2hhcmVkS2V5In0K",
           "encrypted_key": "Pe15h6BYJ7SrEq0ev8m9ce4vq4phLFJK"
           "integrity_value": "b2ersuWujfIaoghd5kOpWw"
       }],
       "initialization_vector": "hRskpf3RwFQmEKQ5",
       "ciphertext": "jZpHMF7GhBNYSD5QIJkBXWu6POh_KTN5"
   }

                                 Figure 5

Barnes                   Expires October 5, 2013                [Page 9]
Internet-Draft                JOSE Refactor                   April 2013

   PROPOSED-JSON:
   {
       "alg": {
           "name": "A128GCM",
           "iv": "hRskpf3RwFQmEKQ5"
       },
       "key": {
           "alg": "A128KW",
           "key": "preSharedKey",
           "data": "Pe15h6BYJ7SrEq0ev8m9ce4vq4phLFJK"
       },
       "data": "jZpHMF7GhBNYSD5QIJkBXWu6POh_KTN5",
       "mac": "b2ersuWujfIaoghd5kOpWw"
   }

                                 Figure 6

5.2.  AES-GCM with AES-GCM wrapping

   The proposed syntax uses JWE to wrap the keys used for JWE.  This
   allows key wrapping to take advantage of all of the algorithms
   available for content encryption.  So while key wrapping with AES-GCM
   is impossible with current JWE specification, the proposed
   modification makes it possible, in both JSON and compact form.

   The JSON syntax shows how the parameters are laid out.  The "alg"
   parameter at the top level specifies the parameters for the content
   encryption.  The "key" parameter at the top level contains the
   wrapped key as a JWE, with its own "alg" parameter specifying
   independent parameters for GCM.  The "data" attribute of the "key"
   object (key.data) contains the wrapped key, and the "mac" attribute
   (key.mac) contains the GCM integrity check value over the key.  The
   "data" and "mac" attributes at the top level contain the encrypted
   content and its integrity check value.

   A recipient would process this JWE in the same manner as a normal
   JWE.  First, the recipient decrypts the key using the GCM parameters
   inside the "key" parameter and the key identified by "preSharedKey".
   Second, the recipient decrypts the content using the top-level GCM
   parameters and the unwrapped key.

Barnes                   Expires October 5, 2013               [Page 10]
Internet-Draft                JOSE Refactor                   April 2013

   PROPOSED-JSON:
   {
       "alg": {
           "name": "A128GCM",
           "iv": "wkir6xYeu2uYfCRM"
       },
       "key": {
           "alg": {
               "name": "A128GCM",
               "iv": "F6va6e3mFryvrk34"
           }
           "key": "preSharedKey",
           "data": "R1mdiiHJvI98Dh634xPN4Q",
           "mac": "Ia5YAJ6XniSL3WGBSlbkXA"
       },
       "data": "6J1u_z-LhIm0GsDVV6o-s_1p2MKJFq5_",
       "mac": "e3LqKZrivwH-oHtsa1TStQ"
   }

                                 Figure 7

   Even though this object uses parameters that cannot be accounted for
   in the current JWE compact encoding, it can still be rendered in the
   compact encoding.  The parameters that the compact encoding
   accommodates are moved out of the header, including the top-level IV,
   the encrypted key, the ciphertext, and the integrity check value.
   The other binary parameters (the key wrapping IV and integrity check
   value) remain in the header.

   PROPOSED-COMPACT-HEADER:
   {"alg":"A128GCM","key":{"alg":{"name":"A128KW",
    "iv":"F6va6e3mFryvrk34"},"key":"preSharedKey",
    "mac":"Ia5YAJ6XniSL3WGBSlbkXA"}}

   PROPOSED-COMPACT:
   eyJhbGciOiJBMTI4R0NNIiwia2V5Ijp7ImFsZyI6eyJuYW1lIjoiQTEyOEt
   XIiwiaXYiOiJGNnZhNmUzbUZyeXZyazM0In0sImtleSI6InByZVNoYXJlZE
   tleSIsIm1hYyI6IklhNVlBSjZYbmlTTDNXR0JTbGJrWEEifX0K
   .R1mdiiHJvI98Dh634xPN4Q
   .wkir6xYeu2uYfCRM
   .6J1u_z-LhIm0GsDVV6o-s_1p2MKJFq5_
   .e3LqKZrivwH-oHtsa1TStQ

                                 Figure 8

   This compact encoding is larger than the one in the previous example
   (264 vs. 209 octets), but 25% shorter than the base64url-encoded
   serialization of the JSON form (264 vs. 352 octets).

Barnes                   Expires October 5, 2013               [Page 11]
Internet-Draft                JOSE Refactor                   April 2013

6.  Rationale

6.1.  Requirements and Goals

   In the course of the key wrapping discussions in JOSE, a few new
   requirements have arisen:

   o  Wrap private and symmetric keys

   o  Wrap keys with attributes attached.

   o  Wrap keys using general AEAD algorithms (e.g., AES-GCM)

   o  Encrypt keys and JWEs with password-based encryption

   A design goal in meeting these requirements should be to duplicate
   functionality as little as possible.  For example, it would violate
   this goal to have JWE define one way of encrypting a symmetric key
   with no attributes, and for a JWK key wrapping specification to
   define another.  In addition, we would like to avoid the need for
   obscure algorithms, in particular RSA-KEM.

   With the above requirements and goals in mind, compare the algorithm
   requirements of JWE and wrapped JWK:

                          JWE     JWK
   AES-GCM & other AEAD    X       X
   AES Key Wrap                    X
   RSA Encryption                  X
   Key Agreement                   X
   Password-based Enc.     X       X

                                 Figure 9

   It makes one wonder whether it might make sense to use the same
   framework for both of these.

6.2.  JWE vs Key Wrapping

   As a starting point for considering whether we can align JWE and
   wrapped JWKs, let's compare a JWE performing direct encryption with
   AES-GCM with a notional wrapped key using AES-KW derived from the JWE
   wrapped key format:

Barnes                   Expires October 5, 2013               [Page 12]
Internet-Draft                JOSE Refactor                   April 2013

   JWE (notional)                            JWE Key Wrap (notional)
   -------------------------------------   ----------------------------
   {                                        {
     alg: "dir"
     enc: "A128GCM",                          alg: "A128KW",
     iv:  "...",
     kid: "this",                             kid: "that",
     data:"..."                               data:"..."
     mac: "..."
   }                                        }
   -------------------------------------   ----------------------------

                                 Figure 10

   Here I've assigned some names in JSON to fields that don't have names
   in JWE.  I've labeled the JWE Initialization Vector as "iv", the JWE
   Ciphertext as "data", and the JWE Integrity Value as "mac".

   Now, suppose we say that a missing "alg" parameter means that "alg"
   is assumed to be direct.  This isn't too unreasonable, since "alg"
   indicates a key wrapping algorithm, and there's no key wrapping going
   on here.  Then we can omit the alg parameter:

   JWE (modified)                          JWE Key Wrap (notional)
   -------------------------------------   ----------------------------
   {                                        {
     enc: "A128GCM", iv: "...",               alg: "A128KW",
     kid: "this",                             kid: "that",
     data:"..."                               data:"..."
     mac: "..."
   }                                        }
   -------------------------------------   ----------------------------

                                 Figure 11

   The two objects start to look very similar now.  They each have three
   critical sections:

   1.  A specification of the encryption algorithm and any necessary
       parameters.  (AES-KW requires no parameters, of course.)

   2.  An identifier for the key being used

   3.  The ciphertext output of the algorithm We can make the syntax
       match this conceptual model if we just put the parameters in an
       object together with the algorithm name.  For symmetry, we'll
       call the algorithm parameter "alg" in both cases; we'll rename
       "kid" to "key" for reasons that will be apparent in a moment.

Barnes                   Expires October 5, 2013               [Page 13]
Internet-Draft                JOSE Refactor                   April 2013

   JWE (modified)                          JWE Key Wrap (notional)
   -------------------------------------   ----------------------------
   {                                        {
     alg: {name: "A128GCM", iv: "..."},       alg: "A128KW",
     key: "this",                             key: "that",
     data:"..."                               data:"..."
     mac: "..."
   }                                        }
   -------------------------------------   ----------------------------

                                 Figure 12

   So with a few minor simplifications to the JWE header format, we've
   created a structure that applies naturally to both general encryption
   (JWE) and key encryption specifically (JWK Key Wrap).  The only
   difference is the "mac" field, which can be optional, since AES-KW
   has an internal integrity check, much like AES-CCM.

6.3.  JWE with Wrapped Keys

   Now, how do we deal with JWEs that use a wrapped CMK in this
   framework?  Well, the whole point of the last section was to make
   JWEs the same as wrapped keys - so we allow the "key" attribute to be
   a JWE containing the wrapped CMK.  For example, if we combine the two
   objects from the previous section, we can have a JWE representing an
   encryption with AES-GCM under a key protected with AES-KW.

   {
       alg: {
           name: "A128GCM",
           iv: "..."
       },
       key: {
           alg: "A128KW",
           key: "that",
           data: "..."
       },
       data: "..."
       mac: "..."
   }

                                 Figure 13

   This gives a simple, self-similar structure for wrapped keys.  The
   self-similarity allows us to transparently account for more advanced
   use cases.  For example, if someone wanted to use a CMK that came
   along with a bunch of attributes, they could use RSA to wrap another
   symmetric key, and use AES-GCM to wrap the CMK.

Barnes                   Expires October 5, 2013               [Page 14]
Internet-Draft                JOSE Refactor                   April 2013

   {
       alg: {
           name: "A128GCM",
           iv: "..."
       },
       key: {
           alg: "A128GCM",
           key: {
               alg: "RSA-OAEP",
               key: /* JWK public key */
               data: "..."
           },
           data: "..."
       },
       data: "..."
       mac: "..."
   }

                                 Figure 14

   The example looks kind of ridiculous, but it's not entirely far-
   fetched.  You could imagine it happening, for example, if a system
   were distributing content decryption keys with attributes, and a
   recipient patched one into a JWE to decrypt it with a JWE library.

   The decryption process can handle the self-similarity naturally with
   recursion.  If the "key" value in the JWE you're processing is a key
   you know (e.g., a "kid" for a key you have), then you use that key.
   Otherwise, you process the "key" value as a JWE and use the decrypted
   content to decrypt the JWE you started with.  In other words, you
   recursively process encrypted keys until you hit a key you know, then
   work your way back up the stack decrypting as you go.

   +------+      +------+      +------+
   | alg  |  +-->| alg  |  +-->| alg  |
   +------+  |   +------+  |   +------+
   | key  |--+-->| key  |--+-->| key  |---+ = known key / ID
   +------+  |   +------+  |   +------+   |
   | data |  +-->| data |  +-->| data |<--+ decrypts
   +------+      +------+      +------+
        ^           | ^           |
        |           | |           |
        +-----------+ +-----------+
           decrypts      decrypts

                                 Figure 15

   Obviously, this sort of recursion could be dangerous, since you could

Barnes                   Expires October 5, 2013               [Page 15]
Internet-Draft                JOSE Refactor                   April 2013

   end up with many levels of recursion, resulting in memory overflows,
   etc.  However, it doesn't seem likely that many levels will be
   necessary in practice, so we could specify that implementations
   should impose limits on the number of levels of recursion that they
   will allow.

   To see how the format outlined above compares to JWE, let's look at
   how the normal JWE fields map to the fields in the example object
   above.

   {
       alg: {
           name: "A128GCM",    <--- "enc"
           iv: "..."           <--- JWE Initialization Vector
       },
       key: {
           alg: "A128KW",      <--- "alg"
           key: "that",        <--- "kid"
           data: "..."         <--- JWE Encrypted Key
       },
       data: "..."             <--- JWE Ciphertext
       mac: "..."              <--- JWE Integrity Value
   }

                                 Figure 16

   As you can see, there's no new information here, just the same fields
   rearranged so that there's less need for special handling of IVs or
   Encrypted Keys - they're just a natural part of the format.

   One last thing: We've said that the "data" value corresponding to the
   JWE Encrypted Key contains a JWK representing the CMK.  In order for
   that value not to impose additional overhead for symmetric keys (by
   wrapping a JSON-encoded key instead of the raw key octets), it will
   be necessary to have a compact format for JWKs.  Such a format should
   produce a raw octet string for symmetric keys with now attributes,
   and may produce an optimized JSON format for other types of keys.  A
   few candidate algorithms are discussed in the detailed considerations
   below.

6.4.  Impact on the Compact Format

   So far, we've been talking about a JSON format, equivalent to the
   current JSON serialization.  How does one take one of these and
   serialize it to something like the JWE compact encoding?  The obvious
   answer is to keep the other fields the same, and just change the
   header to accommodate the revised JSON form.  So the example we just
   considered would serialize as a normal JWE, but with the above JSON

Barnes                   Expires October 5, 2013               [Page 16]
Internet-Draft                JOSE Refactor                   April 2013

   object as the header, and JWE Initialization Vector, JWE Encrypted
   Key, and JWE Ciphertext removed (since they'll be binary components
   afterward).

   {
       alg: {
           name: "A128GCM",    <--- "enc"
       },
       key: {
           alg: "A128KW",      <--- "alg"
           key: "that",        <--- "kid"
       },
   }

                                 Figure 17

   To see the impact on header size, let's compare this header with the
   comparable normal JWE header:

   {"alg":{"name":"A128GCM"},"key":{"alg":"A128KW","key":"that"}}
   {"enc":        "A128GCM" ,       "alg":"A128KW","kid":"that" }
          ........         . .......                           .

                                 Figure 18

   The overhead of this proposed change is thus 17 octets of header,
   which comes to 20 octets after base64url encoding.  So while this
   does change the header structure - so it will break compatibility
   with existing implementations - it doesn't change the overall
   structure of a JWE, and doesn't add a dramatic amount of overhead.

   In fact, one could argue that this makes the compact form even more
   flexible.  The current compact form has no way to accommodate, for
   example, the double-wrapped case above.  In the revised header
   structure, the double-wrapped key would still work: The wrapped CMK
   would be removed to a binary part, and the secondary wrapped key
   would remain in the header.  It would be gigantic, but it would work.

6.5.  JWS

   The same story makes sense for JWS, with a couple of revisions.
   First, JWS signatures with asymmetric keys don't need wrapped keys,
   so their "key" values would just be a JWK for the public key.  (Other
   metadata parameters, such as "x5c" could live at the same level as
   the "alg", and "key" parameters, or in the JWK.)  On the other hand,
   JWS objects that encode MACs could benefit from having wrapped keys
   in the "key" field.

Barnes                   Expires October 5, 2013               [Page 17]
Internet-Draft                JOSE Refactor                   April 2013

   The second major difference is that for JWS, it is sometimes
   desirable to store the input to to cryptographic operation (the
   signed data) in addition to the output (the signature).  In the JWE
   examples above, the "data" field represents the output of the
   cryptographic operation.  So it would be good to define an
   additional, optional field for JWS, which would contain an octet
   string for the protected data.  If that field were present, the JWS
   could be process directly; otherwise, it would represent a detached
   signature.

6.6.  Summary

   In the above, we've described a proposed change to the JWE and JWS
   headers to move away from a flat bag of parameters, toward a
   structure with two required fields and two optional fields:

   1.  REQUIRED: "alg", containing parameters to describe the algorithm
       used to process the JWE/JWS object

   2.  REQUIRED: "key", containing the key used to process the JWE/JWS,
       either directly, in wrapped form, or as an ID

   3.  OPTIONAL: "data", containing the ciphertext (JWE) or signed data
       (JWS)

   4.  OPTIONAL: "mac", containing the MAC or signature value for the
       JWE/JWS object

   This revised structure doesn't lose any features relative to the
   current format, since other header fields like "zip" can still be
   added to the header.  And it imposes low length overhead, in the low
   tens of octets.

   This simpler structure makes it possible to address all of the
   requirements above with out significant changes to JWE and JWS.  In
   fact, it goes beyond the design goals - instead of having one way to
   encrypt keys, we have one way to encrypt anything at all.

Barnes                   Expires October 5, 2013               [Page 18]
Internet-Draft                JOSE Refactor                   April 2013

7.  Revised JSON Format and Translation to Compact

   In the discussion above, we've outlined a JSON structure that
   provides some richer structure than the current JWE header.  This
   requires us to modify somewhat the mapping between a JSON-serialized
   JWE or JWS object and its compact encoding.  In this section, we
   describe the mapping in detail for JWE.  With a minor change to the
   JWS compact serializatoin (adding fields for IV and encrypted key,
   which can be left empty), the same translation can be used for both
   JWE and JWS.

7.1.  Translation from JSON to Compact

   Input: JSON object X representing a JWE object in the JSON
   serialization

   o  Set the Encoded JWE Encrypted Key to X.key.data.  If X.key is not
      present, set it to the empty string.

   o  Set the Encoded JWE Initialization Vector to X.alg.iv.  If X.alg
      is not present, set it to the empty string.

   o  Set the Encoded JWE Ciphertext to X.data

   o  Set the Encoded JWE Integrity Value to X.mac

   o  Delete the "data" field from X.key, the "iv" field from X.alg, and
      the "data" and "mac" fields from X

   o  Base64url encode the bytes of the UTF-8 representation of the X to
      create the Encoded JWE Header.

   o  Assemble the final representation: The Compact Serialization of
      this result is the concatenation of the Encoded JWE Header, the
      Encoded JWE Encrypted Key, the Encoded JWE Initialization Vector,
      the Encoded JWE Ciphertext, and the Encoded JWE Integrity Value in
      that order, with the five strings being separated by four period
      ('.') characters.

   Output: Text string representing a JWE object in the compact
   serialization

   The following JavaScript functions implement this translation, first
   for the current JSON serialization and second for the proposed
   serialization (as described above).

Barnes                   Expires October 5, 2013               [Page 19]
Internet-Draft                JOSE Refactor                   April 2013

   function json2compact_current(obj) {
       var JWE_key  = obj.recipients[0].encrypted_key;
       var JWE_iv   = obj.initialization_vector;
       var JWE_data = obj.ciphertext;
       var JWE_mac  = obj.recipients[0].integrity_value;

       var JWE_header = obj.recipients[0].header;

       return [
           JWE_header,
           JWE_key,
           JWE_iv,
           JWE_data,
           JWE_mac
       ].join(".");
   }

   function json2compact_proposed(obj) {
       var JWE_key  = obj.key.data;
       var JWE_iv   = obj.alg.iv;
       var JWE_data = obj;
       var JWE_mac  = obj.mac;

       delete obj.key.data;
       delete obj.alg.iv;
       delete obj.data;
       delete obj.mac;
       var JWE_header = base64url(JSON.stringify(obj));

       return [
           JWE_header,
           JWE_key,
           JWE_iv,
           JWE_data,
           JWE_mac
       ].join(".");
   }

                                 Figure 19

7.2.  Translation from Compact to JSON

   Input: Text string representing a JWE object in the compact
   serialization

   o  Split the string on the period ('.') character to obtain the
      Encoded JWE Header, the Encoded JWE Ciphertext, and the Encoded
      JWE Integrity Value.

Barnes                   Expires October 5, 2013               [Page 20]
Internet-Draft                JOSE Refactor                   April 2013

   o  Base64url decode the Encoded JWE Header and parse it into a JSON
      object X

   o  Set the field X.key.data to the Encoded JWE Encrypted Key

   o  Set the field X.alg.iv to the Encoded JWE Initialization Vector

   o  Set the field X.data to the Encoded JWE Ciphertext

   o  Set the field X.mac to the Encoded JWE Integrity Value

   Output: JSON object X representing a JWE object in the JSON
   serialization

   The following JavaScript functions implement this translation, first
   for the current JSON serialization and second for the proposed
   serialization (as described above).

   function compact2json_current(str) {
       var parts = str.split(".");
       var obj = { recipients: [{}], };

       obj.recipients[0].header = parts[0];
       obj.recipients[0].encrypted_key = parts[1];
       obj.recipients[0].integrity_value = parts[4];
       obj.initialization_vector = parts[2];
       obj.ciphertext = parts[3];

       return obj;
   }

   function compact2json_proposed(str) {
       var parts = str.split(".");
       var obj = JSON.parse(parts[0]);

       obj.key.data = parts[1];
       obj.alg.iv   = parts[2];
       obj.data     = parts[3];
       obj.mac      = parts[4];

       return obj;
   }

                                 Figure 20

Barnes                   Expires October 5, 2013               [Page 21]
Internet-Draft                JOSE Refactor                   April 2013

8.  Disposition of Header Fields (Proposal Part 3)

   The refactoring of the JWE and JWS headers described above requires
   adding one new field to the header ("key") and redefining one field
   ("alg").

   The new "key" header subsumes the functionality of the "kid" and
   "jwk" headers; it allows a key to be expressed either directly (as a
   "jwk" object) or indirectly (as a "kid" string).  (We could also just
   require that either "kid" or "jwk" be present.)  With the extension
   of JWK to wrapped keys, "key" would also support the use of wrapped
   keys.

   The re-defined "alg" header would collect all the parameters
   describing an algorithm into a single object, whose format would be
   defined in the revised JWA document.  For example, an "alg" value for
   a key agreement algorithm would have a "name" field indicating the
   key agreement algorithm (as in the current "alg" field), as well as
   the "epk", "apu", and "apv" fields from the current JWE object.  An
   "alg" value for symmetric encryption with AES-GCM would include a
   "name" field and an "iv" field with an Initialization Vector.

   The refactoring has no effect on the many JWE and JWS fields that are
   secondary to cryptographic processing.  For example, the "cty" field
   remains at the top level of the header.

   In the following tables, we assign each of the current JWS and JWE
   header fields one of the following dispositions:

   o  Key: Subsumed by "key" field (or an alternative instantiation of
      it)

   o  Alg: Subsumed by "alg" field (move to the JWA)

   o  Hdr: Remains as a header parameter

   JWS Fields     Key     Alg     Hdr
     "alg"                         X
     "jku"                         X
     "jwk"         X
     "x5u"                         X
     "x5t"                         X
     "x5c"                         X
     "kid"         X
     "typ"                         X
     "cty"                         X

Barnes                   Expires October 5, 2013               [Page 22]
Internet-Draft                JOSE Refactor                   April 2013

                                 Figure 21

   JWE Fields     Key     Alg     Hdr
     "alg"                         X
     "enc"         X
     "epk"         X
     "zip"                         X
     "jku"                         X
     "jwk"         X
     "x5u"                         X
     "x5t"                         X
     "x5c"                         X
     "kid"         X
     "typ"                         X
     "cty"                         X
     "apu"                 X
     "apv"                 X
     "epu"                 X
     "epv"                 X

                                 Figure 22

Barnes                   Expires October 5, 2013               [Page 23]
Internet-Draft                JOSE Refactor                   April 2013

9.  Key Wrapping Procedure (Proposal Part 4)

   At a high level, there are two steps in the key wrap.  First, the
   JSON dictionary for the original JWK is split into "public" and
   "private" dictionaries, by dictionary key.  The private dictionary is
   marshaled using a marshaling algorithm (see below), then encrypted in
   a JWE.  The public dictionary becomes the "kat" attribute of the JWE.

   Key unwrapping proceeds in the opposite direction, retrieving the
   public and private dictionaries from the "kat" and "wk" attributes
   (unwrapping the private part), then merging the two into a final JWK.

         +--> pub  -----------------------> "kat"
         |
   key --+
         |
         +--> priv -> marshal -> encrypt -> "data"

                                 Figure 23

   The procedures in this section do not presume a given marshaling
   algorithm.  Instead we discuss several possible options below.  Each
   marshaling procedure has the same interface:

   o  Inputs:

      *  Key type ("kty")

      *  JSON dictionary

   o  Output:

      *  Octet string with the marshaled value

      *  Binary flag indicating whether the marshaled value contains
         JSON content

   The corresponding unmarshaling procedures have corresponding inputs
   and outputs (octet string + binary and JSON dictionary,
   respectively).

9.1.  Wrapping procedure

   Parameters: Marshaling algorithm

   Input: JWK object, wrapping algorithm, wrapping key, list of private
   fields

Barnes                   Expires October 5, 2013               [Page 24]
Internet-Draft                JOSE Refactor                   April 2013

   o  Construct a private object by copying all private fields (listed
      in the list of private fields) from the input JWK to a new
      dictionary

   o  Construct a public object by copying all other fields from the
      input JWK to a new dictionary

   o  Marshal the private object using the marshaling algorithm, and
      record the value of the returned "wj" flag

   o  Create a JWE encrypting the marshaled private object with the
      wrapping algorithm and wrapping key

   o  If the "wj" flag is set to true, add it to the JWE as the "wj"
      attribute

   o  If the public object is non-empty, add it to the JWE as the "kat"
      attribute

   o  Return the JWE

   Output: JWE object with optional "kat" and "wj" attributes

9.2.  Unwrapping Procedure

   Parameters: Marshaling algorithm

   Input: JWE object with optional "kat" and "wj" attributes

   o  Initialize the unwrapped key to an empty JSON dictionary

   o  If the "kat" field is present in the JWE, copy its contents into
      the unwrapped key

   o  Set the "wj" flag to false if it is not present in the JWE

   o  Decrypt the JWE to obtain the marshalled private dictionary

   o  Unmarshal the private dictionary, using the marshaling algorithm
      and the "wj" flag

   o  Copy all fields from the private dictionary into the unwrapped key
      dictionary, overwriting existing fields if necessary

   o  Return the unwrapped key dictionary

   Output: Unwrapped dictionary

Barnes                   Expires October 5, 2013               [Page 25]
Internet-Draft                JOSE Refactor                   April 2013

10.  Compact JWK Marshaling (Proposal Part 4)

   There are several possible compact serializations for JWK, which
   offer different trade-offs between size and complexity.

   o  JWKS0: UTF-8

   o  JWKS1: UTF-8, or raw binary for symmetric keys with no attributes

   o  JWKS2: UTF-8, or raw binary for one field per key type

   o  JWKS3: UTF-8, with raw binary for a fixed list of fields per key
      type

   o  JWKS4: UTF-8, with raw binary for an arbitrary list of fields

   In this section, we describe details for JWKS2 and JWKS3, since JWKS2
   doesn't have significantly more complexity than JWKS1, and JWKS3 is
   much simpler than JWKS4.  For brevity, we list only the encoding
   procedures.

   To illustrate the trade-offs of these algorithms, we consider three
   test cases:

   o  A 256-bit AES key

   o  A 256-bit EC private key

   o  A 2048-bit RSA private key

   In addition to the two above algorithms, we also consider the simple
   wrapping procedure in which the entire JWK is serialized to UTF-8 and
   wrapped as a JWE.

10.1.  JWKS2

   Parameters: Table with one binary field for each key type

   Input: JSON dictionary, key type

   o  If the key type is in the table, and the only field in the
      dictionary is the binary field for the key type

      *  Set the "wj" flag to false

      *  Set the marshaled JSON to the binary contents of the field

Barnes                   Expires October 5, 2013               [Page 26]
Internet-Draft                JOSE Refactor                   April 2013

   o  Else

      *  Set the "wj" flag to true

      *  Set the marshaled JSON to the UTF-8 serialization of the JSON
         dictionary

   Output: Marshaled JSON, "wj" flag

10.2.  JWKS3

   Parameters: Table with a list of binary fields for each key type

   Input: JSON dictionary, key type

   o  If the key type is not in the table:

      *  Set the "wj" flag to true

      *  Set the marshaled JSON to the UTF-8 serialization of the JSON
         dictionary

   o  If the key type is in the table and there is only one binary field
      in the list for this key type, and that field is the only field in
      the JSON dictionary:

      *  Set the "wj" flag to false

      *  Set the marshalled JSON to the binary contents of the field

   o  Else if the key type is in the table:

      *  Set the "wj" flag to false

      *  Copy all binary fields from the JSON dictionary to a new
         dictionary, then remove them from the JSON dictionary

      *  If the JSON dictionary is non-empty, compute its UTF-8
         serialization and set the "wj" flag to true

      *  Construct a list of binary components containing:

         +  The serialized JSON dictionary, if non-empty

         +  The cached binary field values, in the order of the list of
            fields

Barnes                   Expires October 5, 2013               [Page 27]
Internet-Draft                JOSE Refactor                   April 2013

      *  Prefix each binary component with a two-octet length field

      *  Set the marshaled JSON to the concatenation of the length-
         prefixed binary components

   Output: Marshaled JSON, "wj" flag

10.3.  Test Cases

   Test case 1: A 32-bit symmetric key, with the single private field
   "k"

   { "kty": "oct", "k": "cSax0MQz66lGh7hMsgNm8mC+hS+DplWW7o+yUVVIINU=" }

                                 Figure 24

   Test case 2: A 256-bit EC private key, with the single private field
   "d"

   {
       "kty": "EC",
       "crv": "P-256",
       "kid": "1",
       "x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
       "y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
       "d": "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE"
   }

                                 Figure 25

   Test case 3: A 2048-bit RSA private key, with six private fields "d",
   "p", "q", "dp", "dq", "qi".

   {
       "kty": "RSA",
       "alg": "RS256",
       "kid": "2011-04-29",
       "n": /* 256 octets */,
       "e": "AQAB",
       "d": /* 256 octets */,
       "p": /* 128 octets */,
       "q": /* 128 octets */,
       "dp": /* 128 octets */,
       "dq": /* 128 octets */,
       "qi": /* 128 octets */,
   }

                                 Figure 26

Barnes                   Expires October 5, 2013               [Page 28]
Internet-Draft                JOSE Refactor                   April 2013

10.4.  Performance on Test Cases

   To characterize the performance of the marshaling algorithms on the
   test cases, we compute the number of octets used to represent the
   wrapped key in the JWE (omitting other JWE parameters, which are
   constant).

   We consider four cases:

   1.  Baseline: Length of the UTF-8 serialization of the JWK

   2.  Simple: Length of the base64url-encoded UTF-8 serialization of
       the JWK

   3.  JWKS2: Length of UTF-8 serialization of the public half of the
       JWK (as would be in the "kat" field), plus the length of the
       base64url-encoded output of JWKS2 on the private half

   4.  JWKS3: Same as JWKS2, but using JWKS3 instead

   The results of this analysis are as follows:

   Test Case      1     2     3
                AES    EC   RSA
   ============================
   Baseline      64   186  1648
   Simple        88   248  2200
   JWKS2         44   180  2066
   JWKS3         44   180  1634

                                 Figure 27

   As expected, the compact JWKS serializations are more compact in
   general than the simple approach, because they avoid double-base64
   encoding.  For test case 2, which involves multiple binary fields in
   the wrapped key, JWKS2 does a little better than the simple approach
   because it can handle one field ("d"), and JWKS3 does notably better
   because it can handle all of the binary fields.

Barnes                   Expires October 5, 2013               [Page 29]
Internet-Draft                JOSE Refactor                   April 2013

11.  Security Considerations

   The refactoring proposed in this document has several security
   benefits.

   First, by using the JWE format for wrapped keys in JWE, JWE can
   benefit from general AEAD algorithms for key wrapping, for example,
   AES-GCM as opposed to AES key wrap.  These other AEAD algorithms are
   more widely available than AES key wrap, and offer better security
   properties in some situations.  This benefit is available to the
   compact serialization as well as the revised JSON format.

   Second, by using the same format for key encryption and content
   encryption, code for processing objects in the proposed format will
   only have to have support one way of decrypting objects.  This
   simplification will reduce the chance for bugs in implementations.

   Third, the use of consolidated algorithm and key objects allows for
   simpler validation rules on JOSE objects, again reducing the chance
   that an improperly-constructed JOSE object will be able to trigger
   implementation bugs.

   The current JWE and JWS specifications require header information to
   be protected under the integrity check provided by the signature,
   MAC, or AEAD algorithm.  This proposal makes the header computation
   slightly more difficult in the JSON case, since the recipient will
   have to reconstruct the header by removing some fields from the JSON
   object.  However, no concrete security benefit has been proposed for
   header integrity, so it may be better to remove header integrity
   protection in order to allow for cleaner architecture.

Barnes                   Expires October 5, 2013               [Page 30]
Internet-Draft                JOSE Refactor                   April 2013

12.  IANA Considerations

   This memo makes no request of IANA.  However, changes to the JOSE
   specs resulting from this proposal might require adjustments to some
   IANA registrations.

Barnes                   Expires October 5, 2013               [Page 31]
Internet-Draft                JOSE Refactor                   April 2013

13.  Normative References

   [I-D.ietf-jose-json-web-algorithms]
              Jones, M., "JSON Web Algorithms (JWA)",
              draft-ietf-jose-json-web-algorithms-08 (work in progress),
              December 2012.

   [I-D.ietf-jose-json-web-encryption]
              Jones, M., Rescorla, E., and J. Hildebrand, "JSON Web
              Encryption (JWE)", draft-ietf-jose-json-web-encryption-08
              (work in progress), December 2012.

   [I-D.ietf-jose-json-web-key]
              Jones, M., "JSON Web Key (JWK)",
              draft-ietf-jose-json-web-key-08 (work in progress),
              December 2012.

   [I-D.ietf-jose-json-web-signature]
              Jones, M., Bradley, J., and N. Sakimura, "JSON Web
              Signature (JWS)", draft-ietf-jose-json-web-signature-08
              (work in progress), December 2012.

Barnes                   Expires October 5, 2013               [Page 32]
Internet-Draft                JOSE Refactor                   April 2013

Author's Address

   Richard Barnes
   BBN

   Email: rlb@ipv.sx

Barnes                   Expires October 5, 2013               [Page 33]