TOC 
DraftD. Balfanz, Ed.
 J. Panzer
 Google Inc.
 September 19, 2010


JSON Tokens

Abstract

This document defines a lightweight, robust mechanism for digitally signing authentication and authorization messages ("JSON Tokens") in a format that's easily included in HTTP requests.

It is a subset and concrete profile of the Magic Signatures (Panzer, J., “Magic Signatures,” .) [MagicSignatures] specification.



Table of Contents

1.  Introduction
    1.1.  Requirements Language
2.  Definitions
3.  JSON Tokens
    3.1.  Payload Parameters
    3.2.  Validating JSON Tokens
4.  Excerpts from the Magic Signatures Specification
    4.1.  Magic Envelope Definition
        4.1.1.  Magic Envelope Parameters
        4.1.2.  The Signature Base String
        4.1.3.  The Magic Envelope Compact Serialization
    4.2.  Encoding of data and sig using base64url
        4.2.1.  Encoding
        4.2.2.  Decoding
    4.3.  The HMAC-SHA256 Private Key Signature Algorithm
        4.3.1.  Calculating the HMAC-SHA256 signature string
        4.3.2.  Signing and Verifying Messages with HMAC-SHA256
    4.4.  The RSA-SHA256 Public Key Signature Algorithm
        4.4.1.  Signing Messages with RSA-SHA256
        4.4.2.  Verifying Messages with RSA-SHA256
        4.4.3.  Magic Public Key Infrastructure
            4.4.3.1.  The application/magic-key MIME type
            4.4.3.2.  Discovery
5.  References
    5.1.  Normative References
    5.2.  Informative References
§  Authors' Addresses




 TOC 

1.  Introduction

JSON Tokens are digitally-signed JSON strings with a prescribed set of parameters in their payload. We use Magic Signatures Compact Serialization (The Magic Envelope Compact Serialization) to encode and sign the JSON payload.

We include in this spec the relevant portions of the Magic Signatures (Panzer, J., “Magic Signatures,” .) [MagicSignatures] spec for reference.



 TOC 

1.1.  Requirements Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 (Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels,” March 1997.) [RFC2119].



 TOC 

2.  Definitions

Signature:
A digital signature that provably binds a message to a signer's secret key.
Signer:
In this specification, a http or https URI used to determine a key used to sign an envelope.



 TOC 

3.  JSON Tokens

A JSON Token comprises a JSON payload bundled along with a signature for that payload, expressed as a series of parameters. JSON Tokens use Magic Envelope Compact Serialization (The Magic Envelope Compact Serialization) to transform the payload and parameters into a string suitable for inclusion in web requests.



 TOC 

3.1.  Payload Parameters

The payload of the Magic Envelope is a JSON object that contains the following parameters:

issuer
A string that allows the verifier to determine the Signer URI. This could be the Signer URI tself, or some form of client id, which the verifier can map to a Signer URI. Type: string
not_before
When does this token become valid (seconds since midnight 1/1/1970 zulu). Type: integer
not_after
When does this token expire (seconds since midnight 1/1/1970 zulu). Type: integer
audience
The audience for this token. The precise semantics of this field, and how it is validated, depends on the application. Type: string



 TOC 

3.2.  Validating JSON Tokens

When receiving a JSON Token, a client can validate the token, provided it has access to a signature verification key (discussed in further detail below). It needs to perform the following steps:

  1. verify the data_type envelope parameter in an application-dependent manner.
  2. extract the key identifier from the token, obtain verification key for the Signer and key identifier (more details below (Magic Public Key Infrastructure)).
  3. using verification key, verify signature on payload as explained in Section 4.3.2 (Signing and Verifying Messages with HMAC-SHA256) and Section 4.4.2 (Verifying Messages with RSA-SHA256).
  4. verify that the current time is not before the not_before timestamp in the payload, and that the current time is not after the expiration time of the token (defined as not_before + token_lifetime). The verifier SHOULD be lenient and anticipate some clock skew on the issuer's side.
  5. verify the audience payload field in an application-dependent manner.



 TOC 

4.  Excerpts from the Magic Signatures Specification

Below we reproduce the relevant sections of the Magic Signatures (Panzer, J., “Magic Signatures,” .) [MagicSignatures] specification for easy reference.



 TOC 

4.1.  Magic Envelope Definition

A "Magic Envelope" comprises a message bundled along with [a] signature for that message, expressed as a series of parameters [...]. The envelope specifies the data to be signed, the MIME type of the data, the transfer encoding, and the signature.



 TOC 

4.1.1.  Magic Envelope Parameters

This section describes the semantics of the [envelope] parameters [...].

data:
The payload covered by the signature, encoded into an ASCII string. [...]
data_type:
The MIME (Freed, N. and N. Borenstein, “Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies,” November 1996.) [RFC2045] type of the payload prior to encoding. [...]
encoding:
The encoding used to convert between the MIME type and the "data" string. In this specification, encoding MUST be the string "base64url", indicating the url safe base64 encoding as described in RFC 4648 (Josefsson, S., “The Base16, Base32, and Base64 Data Encodings,” October 2006.) [RFC4648], with the whitespace normalization rules specified in Section 4.2.1 (Encoding). [...]
alg:
The algorithm used for the signature. This specification describes only one public key signature algorithm, "RSA-SHA256", and one private key signature algorithm, "HMAC-SHA256". Specifications relying on Magic Signatures MUST specify which of these MUST be supported for a particular protocol. Implementations of general Magic Signatures SHOULD support both for maximum interoperability. [...]
sig:
A generated signature. This is a string in the base64url encoded format as described above. It is generated according to the rules for the "alg" in use. [...]
key_id:
Optional hint indicating which specific key owned by the signer should be used to verify the signature. This allows signers to explicitly signal a change of key to recipients. Omitting this parameter is equivalent to setting it to an empty string. The format of this parameter is unspecified except that all characters must be from the base64url allowed character set. Thus, "", "1", "AH478=", "0x6EF37D", and "fred" are all legal key_ids. The exact format is up to the key issuer. Note that any binary data can be converted into an acceptable key_id by base64url encoding it. One way to generate a usable key_id is to base64url-encode the SHA256 hash of the public signing key's magicsig representation; this allows a signer to provide usable ids without maintaining a mapping table.



 TOC 

4.1.2.  The Signature Base String

The Signature Base String used for both RSA-SHA256 and HMAC-SHA256 is described here. It is used as input to the signature algorithms, as well as to create the Compact Serialization (The Magic Envelope Compact Serialization), below.

Given a Magic Envelope with "data", "data_type", "encoding", and "alg" parameters, the corresponding Signature Base String is produced by concatenating the following substrings together, separated by periods (ASCII 0x2E):

  1. The armored string for "data" produced by Section 4.2.1 (Encoding)
  2. The Base64url encoding of the "data_type" parameter
  3. The Base64url encoding of the "encoding" parameter
  4. The Base64url encoding of the "alg" parameter

An omitted parameter is represented by a zero length placeholder string.



 TOC 

4.1.3.  The Magic Envelope Compact Serialization

The Magic Envelope Compact Serialization stores the envelope itself in a compact, armored form suitable for storage as a simple string. It is guaranteed to contain no spaces and no URL unsafe characters, and allows for only a single signature.

Given a singly signed envelope with one "sig" and one "key_id", the Compact Serialization is produced by concatenating the following substrings together, separated by periods (ASCII 0x2E):

  1. The value of the "key_id" parameter
  2. The value of the "sig" parameter
  3. The Signature Base String as described in The Signature Base String (The Signature Base String), above.

For example, if the key_id is "4k8ikoyC2Xh+8BiIeQ+ob7Hcd2J7/Vj3uM61dy9iRMI=", the "sig" is "EvGSD2vi8qYcveHnb-rrlok07qnCXjn8YSeCDDXlbhILSabgvNsPpbe76up8w63i2fWHvLKJzeGLKfyHg8ZomQ", and the armored data is "Tm90IHJlYWxseSBBdG9t" with MIME type application/atom+xml, then the Compact Serialization would be the string: "4k8ikoyC2Xh+8BiIeQ+ob7Hcd2J7/Vj3uM61dy9iRMI=.EvGSD2vi8qYcveHnb-rrlok07qn CXjn8YSeCDDXlbhILSabgvNsPpbe76up8w63i2fWHvLKJzeGLKfyHg8ZomQ.Tm90IHJlYWxse SBBdG9t.YXBwbGljYXRpb24vYXRvbSt4bWw=.YmFzZTY0dXJs.UlNBLVNIQTI1Ng=="

Any parameter MAY be omitted by leaving its slot empty, as indicated by two consecutive periods. When the "encoding" parameter is omitted, a recipient MUST decode the envelope as if it had the value "base64url". When the "alg" parameter is omitted, a recipient MUST interpret the message as if the "alg" parameter had the value "RSA-SHA256". The "data_type" parameter SHOULD NOT be omitted as it provides a defense against content type masquerading attacks.



 TOC 

4.2.  Encoding of data and sig using base64url

The data and sig fields of a Magic Envelope are encoded as armored ASCII strings using a procedure chosen to be robust in the face of various types of transports and storage systems. Specifically, the encoded form is safe to include directly as text in XML, a string in JSON, a parameter in URLs, or as form data, without escaping. This section defines the mapping between arbitrary binary data (a stream of octets) and the armored form (an ASCII string). The ASCII string is also chosen so as to be a valid and equivalent UTF-8 string.



 TOC 

4.2.1.  Encoding

The basic procedure is to use the URL and Filename safe variant of the base64 encoding as described in RFC 4648 (Josefsson, S., “The Base16, Base32, and Base64 Data Encodings,” October 2006.) [RFC4648], section 5, hereafter known as "base64url" encoding. The result is a string that consists only of the ASCII alphanumeric characters along with '-' and '_', and possibly '='. In regular expression form, this is "^[A-Za-z0-9\-_]*=?=?=?$". This is the normalized form of the encoded data, and is the basis for the octet sequence that is used to generate the digital signature. Implementations and transports MAY add arbitrary whitespace (ASCII values 0x09-0x0D and 0x20) anywhere in this string after signing but before output so as to, e.g., comply with line length restrictions in certain environments.



 TOC 

4.2.2.  Decoding

The basic procedure is the reverse of encoding, with the additional step that whitespace from the input should be ignored. This is necessary for robustness because some transports may insert whitespace, and is useful to allow for human readable formatting of documents in any case.

  1. Normalize the string by removing all whitespace characters from input.
  2. Base64url decode the resulting string to produce the original binary data.



 TOC 

4.3.  The HMAC-SHA256 Private Key Signature Algorithm

This section defines a basic HMAC based private key signature algorithm. HMAC key exchange and rotation is outside the scope of this specification, but may be defined in specifications relying on this one.



 TOC 

4.3.1.  Calculating the HMAC-SHA256 signature string

First, create an HMAC-SHA256 signature using the algorithm described in RFC 2104 (Krawczyk, H., Bellare, M., and R. Canetti, “HMAC: Keyed-Hashing for Message Authentication,” February 1997.) [RFC2104], using SHA-256 as the hash function H, base string described in Section 4.1.2 (The Signature Base String) as the input text, and the shared secret key K. The resulting array of bytes is then base64url encoded to produce the "sig" parameter.



 TOC 

4.3.2.  Signing and Verifying Messages with HMAC-SHA256

Signing consists of calculating the "sig" parameter and serializing it along with the other parameters to create a Magic Envelope. Verifying consists of re-calculating the expected "sig" parameter given the other parameters, and doing an exact string comparison of the "sig" parameters after normalization (whitespace removal).



 TOC 

4.4.  The RSA-SHA256 Public Key Signature Algorithm

This section defines the default public key signature algorithm for Magic Signatures. In addition to indicating the signing algorithm, use of RSA-SHA256 by default also implies use of the Magic Public Key Infrastructure Section 4.4.3 (Magic Public Key Infrastructure) to obtain public keys. Specifications relying on Magic Signatures MAY specify other mechanisms for key retrieval.



 TOC 

4.4.1.  Signing Messages with RSA-SHA256

Signing a message consists of signing the contents of "data", "data_type", "encoding", and "alg" using the chosen algorithm. This section defines the "RSA-SHA256" algorithm, meaning the RSASSA-PKCS1-v1_5 signature algorithm from RFC 3447 (Jonsson, J. and B. Kaliski, “Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1,” February 2003.) [RFC3447] section 8.2, also known as PKCS#1, using SHA-256 as the hash function for EMSA-PKCS1-v1_5.

Note: As best current crypto practices change, new algorithms will become available and both extensions and future revisions of this specification may include additional new public key algorithms (e.g., RSASSA-PSS). When both clients and servers have sufficiently widespread support for the latest algorithm, older algorithms (e.g., RSASSA-PKCS1-v1_5) will be deprecated and removed in subsequent revisions of this specification.

The signature is computed as signature_octets = RSASSA-PKCS1-V1_5-SIGN (K, M), where K is the private signing key and M is the Signature Base String (The Signature Base String) defined above. Thus M is produced by concatenating the following substrings together, separated by periods (ASCII 0x2E):

  1. The armored string for "data" produced by Section 4.2.1 (Encoding)
  2. The Base64url encoding of the "data_type" parameter
  3. The Base64url encoding of the "encoding" parameter
  4. The Base64url encoding of the "alg" parameter

For example, if the armored data is "Tm90IHJlYWxseSBBdG9t" with MIME type application/atom+xml, then M would be the string: "Tm90IHJlYWxseSBBdG9t.YXBwbGljYXRpb24vYXRvbSt4bWw=.YmFzZTY0dXJs.UlNBLVNIQTI1Ng=="

For convenience we summarize the steps for the required EMSA-PKCS1-v1_5 with RSA-SHA256 algorithm here. In the following, '+' means string concatenation.

  1. Let hash = the SHA256 hash digest of M
  2. Let prefix = the constant byte sequence [0x30, 0x31, 0x30, 0xd, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1, 0x5, 0x0, 0x4, 0x20]
  3. Let k = the number of bytes in the public key modulus
  4. Let padding = '\xFF' repeated (k - length(prefix+hash) - 3) times
  5. Let emsa = '\x00' + '\x01' + padding + '\x00' + prefix + hash
  6. RSA sign the emsa byte sequence

The signature is then encoded as in Section 4.2.1 (Encoding) and the resulting ASCII armored string stored as a "sig" signature. The associated "key_id" is the key_id associated with that signing key and published per Section 4.4.3 (Magic Public Key Infrastructure). If the signer does not maintain individual key_ids, it SHOULD output the base64url encoded respresentation of the SHA-256 hash of public key's application/magic-key representation.



 TOC 

4.4.2.  Verifying Messages with RSA-SHA256

Verifying a message signature consists of verifying that "sig" is a valid signature for "data" using "alg". This specification defines only the "RSA-SHA256" verification algorithm, meaning the RSASSA-PKCS1-v1_5 verification algorithm from RFC 3447 (Jonsson, J. and B. Kaliski, “Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1,” February 2003.) [RFC3447] section 8.2.1.

The verification is performed by executing RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S), where (n ,e) comprise the public key, M is the message string documented in Section 4.4.1 (Signing Messages with RSA-SHA256), and S is the decoded value of a selected "sig". (Note that this algorithm creates the emsa byte sequence as in Section 4.4.1 (Signing Messages with RSA-SHA256) and then performs RSA verification using (n, e), emsa, and S.)[...]

[...] Signers SHOULD ensure that the content expiration is not after the known key expiration time. That is, the signed content should expire no later than the expiration date of the key used to sign it.

Note that emergency key revocation is outside the scope of this specification. However, implementations SHOULD honor HTTP cache control directives when retrieving key material and SHOULD NOT use keys for verification without revalidating the content as directed by the origin server. This allows origin servers to trade off performance for smaller periods of vulnerability.

Unless specified otherwise, the public key (n, e) is obtained using the simple public key infrastructure described by Section 4.4.3 (Magic Public Key Infrastructure). Note that several candidate signing keys may be retrieved, and in the worst case verifiers MUST try each one with equal key_id until at least one successfully verifies the signature. Two key IDs are equal if their individual octets are equal and they are of equal length. A signature with an empty (missing) key_id, which may have been signed by any key, MUST be verified against all available keys.



 TOC 

4.4.3.  Magic Public Key Infrastructure

This section defines a public key infrastructure based on URIs. [...] Specifically, given a Signer URI such as [...] "http://example.com/bob", the corresponding public key(s) for that identifier can be discovered as defined below. The result is a set of RSA public keys in a simple string format.



 TOC 

4.4.3.1.  The application/magic-key MIME type

The application/magic-key format is a very minimal format for representing public key data. It consists of a string of ASCII text, separated into 3 components, with components separated by a "." (0x2E) character. The first component is the key type; this specification only defines the "RSA" key type for future upgradeability. Thus a magic key consists of the string "RSA.modulus(n).exponent(e)"; for example:

RSA.mVgY8RN6URBTstndvmUUPb4UZTdwvwmddSKE5z_jvKUEK6yk1u3rrC9yN8k6FilGj9K0eeUPe2hf4Pj-5CmHww.AQAB

The pair (n, e) is used as input to RSASSA-PKCS1-V1_5-VERIFY.

Each of the components is first represented as an integer in network byte order (big endian) and encoded via the "base64url" mechanism described in Section 4.1.1 (Magic Envelope Parameters).

This specificaion defines only a public key format, and anticipates that keypairs may be stored securely in other formats (e.g., DER encoded X.509 certificates) and that the application/magic-key data will be generated via tools.



 TOC 

4.4.3.2.  Discovery

This section defines how to map from a signer URI identifier to a set of public signing keys for that identifier. [...]

The end result of discovery will be a collection of magic keys. Each magic key has a "data" parameter, a string in application/magic-key format; and an optional "key_id" parameter, a string as defined in [TBD:REF]. If the key_id is omitted from a key, it defaults to the Base64url encoding of the SHA-256 hash of the "value" parameter. That is, when doing discovery, processors MUST assume that an omitted key_id is equivalent to specifying key_id = Base64url(SHA-256(value)). A signer MAY then use this value as a key_id on a signature in order to signal use of that key.[...]



 TOC 

4.4.3.2.1.  The JSON Serialization of Magic Keys

The keys are stored within an array named "magic_keys". The array's values are objects, each of which MUST have a string "value" element containing the application/magic-key string, and which MAY have a string "key_id" element containing the id of that key.

Example:

{
  "magic_keys": [
    {"value": "RSA.mVgY8RN6URBTstndvmUUPb4UZTdwvwmddSKE5z_jvKUEK6yk1u3rrC9yN8k6FilGj9K0eeUPe2hf4Pj-5CmHww.AQAB",
     "key_id": "1"},
    {"value": "RSA.wvwmdK0eeUPe2hURBTstndvmUUPb4UZTd6wvwmddSrrC89yN8k6FilGwvwmddSKE5z_jvKUEKj9f4Pj-5CmHww.AQAB",
     "key_id": "2"}
  ]
}



 TOC 

4.4.3.2.2.  Discovery Flow

Given a [Signer] URI U, [...] directly retrieve the resource U via SSL, performing necessary certificate checks, and see if the resulting data is of type application/metadata+json. If so, look for the "magic_public_keys" array as per the JSON Serialization. [...]



 TOC 

4.4.3.2.3.  Key Selection

Once a set of possible key candidates have been determined, via discovery or alternatively via an extension mechanism outside the scope of this specification, a verifier must then determine whether a given signature is valid. This section details how to do so in an interoperable way.

Among the available keys, select the key for verification by matching the key_id against the key_id specified in the signature. In this context an empty string key_id matches everything. This produces a smaller set of possible keys to use for verification. Verification succeeds if any one of these keys successfully verifies the signature.[...]



 TOC 

5.  References



 TOC 

5.1. Normative References

[RFC2045] Freed, N. and N. Borenstein, “Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies,” RFC 2045, November 1996 (TXT).
[RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, “HMAC: Keyed-Hashing for Message Authentication,” RFC 2104, February 1997 (TXT).
[RFC2119] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels,” BCP 14, RFC 2119, March 1997 (TXT, HTML, XML).
[RFC3447] Jonsson, J. and B. Kaliski, “Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1,” RFC 3447, February 2003 (TXT).
[RFC4648] Josefsson, S., “The Base16, Base32, and Base64 Data Encodings,” RFC 4648, October 2006 (TXT).


 TOC 

5.2. Informative References

[MagicSignatures] Panzer, J., “Magic Signatures.”


 TOC 

Authors' Addresses

  Dirk Balfanz (editor)
  Google Inc.
  1600 Ampitheatre Parkway
  Mountain View, CA
  USA
Phone: 
Email:  balfanz@google.com
  
  John Panzer
  Google Inc.