TOC |
|
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.
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 |
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 |
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 |
- 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 |
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 |
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 |
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:
TOC |
Below we reproduce the relevant sections of the Magic Signatures (Panzer, J., “Magic Signatures,” .) [MagicSignatures] specification for easy reference.
TOC |
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 |
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 |
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):
An omitted parameter is represented by a zero length placeholder string.
TOC |
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):
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 |
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 |
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 |
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.
TOC |
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 |
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 |
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 |
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 |
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):
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.
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
TOC |
[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 |
[MagicSignatures] | Panzer, J., “Magic Signatures.” |
TOC |
Dirk Balfanz (editor) | |
Google Inc. | |
1600 Ampitheatre Parkway | |
Mountain View, CA | |
USA | |
Phone: | |
Email: | balfanz@google.com |
John Panzer | |
Google Inc. |