JWS Unencoded Payload OptionMicrosoftmbj@microsoft.comhttp://self-issued.info/
Security
JOSE Working GroupJavaScript Object NotationJSONJSON Object Signing and EncryptionJOSEJSON Web SignatureJWSDigital SignatureMessage Authentication CodeMACUnencoded Payload
JSON Web Signature (JWS) represents the payload of a JWS as a base64url
encoded value and uses this value in the JWS Signature computation.
While this enables arbitrary payloads to be integrity protected,
some have described use cases in which the base64url encoding is unnecessary
and/or an impediment to adoption, especially when the payload is large and/or detached.
This specification defines a means of accommodating these use cases by
defining an option to change the JWS Signing Input computation to not
base64url-encode the payload.
This option is intended to broaden the set of use cases for which
the use of JWS is a good fit.
This specification updates RFC 7519
by prohibiting the use of this option in JSON Web Tokens (JWTs).
The "JSON Web Signature (JWS)" specification
defines the JWS Signing Input as
the input to the digital signature or MAC computation, with the value
ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload)).
While this works well in practice for many use cases,
including those accommodating arbitrary payload values,
other use cases have been described in which base64url encoding
the payload is unnecessary and/or an impediment to adoption,
particularly when the payload is large and/or detached.
This specification introduces a new JWS Header Parameter value that
generalizes the JWS Signing Input computation in a manner that makes
base64url encoding the payload selectable and optional.
The primary set of use cases where this enhancement may be helpful are those
in which the payload may be very large and where means are already in place
to enable the payload to be communicated between the parties without modifications.
Appendix F of describes how to represent JWSs with
detached content, which would typically be used for these use cases.
The advantages of not having to base64url-encode a large payload are that
allocation of the additional storage to hold the base64url-encoded form is avoided
and the base64url-encoding computation never has to be performed.
In summary, this option can help avoid unnecessary copying and transformations
of the potentially large payload, resulting in sometimes significant space
and time improvements for deployments.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY",
and "OPTIONAL" in this specification are to be interpreted as
described in
"Key words for use in RFCs to Indicate Requirement Levels" .
The interpretation should only be applied when the terms appear in all capital letters.
BASE64URL(OCTETS) denotes the base64url encoding of OCTETS,
per Section 2 of .
UTF8(STRING) denotes the octets of the
UTF-8 representation of STRING,
where STRING is a sequence of zero or more Unicode characters.
ASCII(STRING) denotes the octets of the
ASCII representation of STRING,
where STRING is a sequence of zero or more ASCII characters.
The concatenation of two values A and B
is denoted as A || B.
This specification uses the same terminology as the
"JSON Web Signature (JWS)" and
"JSON Web Algorithms (JWA)"
specifications.
This Header Parameter modifies the JWS Payload representation
and the JWS Signing Input computation in the following way:
The b64 (base64url-encode payload) Header Parameter
determines whether the payload is represented in the JWS and
the JWS Signing Input as ASCII(BASE64URL(JWS Payload))
or as the JWS Payload value itself with no encoding performed.
When the b64 value is false,
the payload is represented simply as the JWS Payload value;
otherwise, it is represented as ASCII(BASE64URL(JWS Payload)).
The b64 value is a JSON boolean,
with a default value of true.
When used, this Header Parameter MUST be integrity protected;
therefore, it MUST occur only within the JWS Protected Header.
Use of this Header Parameter is OPTIONAL.
If the JWS has multiple signatures and/or MACs,
the b64 Header Parameter value
MUST be the same for all of them.
Note that unless the payload is detached,
many payload values
would cause errors parsing the resulting JWSs,
as described in .
The following table shows the JWS Signing Input computation,
depending upon the value of this parameter:
"b64"JWS Signing Input FormulatrueASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload))falseASCII(BASE64URL(UTF8(JWS Protected Header)) || '.') || JWS Payload
This section gives examples of JWSs showing the difference that
using the b64 Header Parameter makes.
The examples all use the JWS Payload value [36, 46, 48, 50].
This octet sequence represents the ASCII characters
$.02;
its base64url-encoded representation is JC4wMg.
The following table shows a set of Header Parameter values
without using a false b64 Header Parameter value
and a set using it,
with the resulting JWS Signing Input values represented as ASCII characters:
JWS Protected HeaderJWS Signing Input Value{"alg":"HS256"}eyJhbGciOiJIUzI1NiJ9.JC4wMg{"alg":"HS256","b64":false}eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2V9.$.02
These examples use the HMAC key from Appendix A.1 of ,
which is represented below as a JWK
(with line breaks within values for display purposes only):
The rest of this section shows complete representations
for the two JWSs above.
The complete JWS representation for this example
using the JWS Compact Serialization
and a non-detached payload
(with line breaks for display purposes only) is:
Note that this JWS uses only features defined by and
does not use the new b64 Header Parameter.
It is the "control", so that differences when it is used can be easily seen.
The equivalent representation for this example
using the flattened JWS JSON Serialization is:
The complete JWS representation for this example
using the JWS Compact Serialization
and a detached payload
(with line breaks for display purposes only) is:
Note that the payload $.02 cannot be represented
in this JWS in its unencoded form because it contains a period ('.') character,
which would cause parsing problems.
This JWS is therefore shown with a detached payload.
The complete JWS representation for this example
using the flattened JWS JSON Serialization
and a non-detached payload is:
If using a detached payload with the JWS JSON Serialization,
the payload element would be omitted.
When the b64 value is false,
different restrictions on the payload contents apply, depending upon the circumstances,
as described in this section.
The restrictions prevent the use of payload values that would cause errors
parsing the resulting JWSs.
Note that because the character sets that can be used for
unencoded non-detached payloads differ between the two serializations,
some JWSs using
a b64 value of false
cannot be syntactically converted between the JWS JSON Serialization and
the JWS Compact Serialization.
See for security considerations
on using unencoded payloads.
Appendix F of describes how to represent JWSs with
detached content.
A detached payload can contain any octet sequence representable by the application.
The payload value will not cause problems parsing the JWS,
since it is not represented as part of the JWS.
If an application uses a content encoding when representing the payload,
then it MUST specify whether the signature or MAC is performed over
the content-encoded representation or over the unencoded content.
When using the JWS Compact Serialization, unencoded non-detached payloads
using period ('.') characters would cause parsing errors;
such payloads MUST NOT be used with the JWS Compact Serialization.
Similarly, if a JWS using the JWS Compact Serialization and a non-detached payload
is to be transmitted in a context that requires
URL safe characters, then the application MUST ensure that
the payload contains only the URL-safe characters 'a'-'z', 'A'-'Z', '0'-'9',
dash ('-'), underscore ('_'), and tilde ('~').
The payload value is the ASCII representation of the characters in the payload string.
The ASCII space character and all printable ASCII characters other than period ('.')
(those characters in the ranges %x20-2D and %x2F-7E)
MAY be included in a non-detached payload using the JWS Compact Serialization,
provided that the application can transmit the resulting JWS without modification.
No meaning or special semantics are attached to any characters in the payload.
For instance, the percent ('%') character represents itself,
and is not used by JWS objects for percent-encoding .
Applications, of course, are free to utilize content encoding rules of their choosing,
provided that the encoded representations utilize only allowed payload characters.
When using the JWS JSON Serialization, unencoded non-detached payloads
must consist of
the octets of the UTF-8 encoding of a sequence of Unicode code points
that are representable in a JSON string.
The payload value is determined after performing any JSON string escape processing,
per Section 8.3 of RFC 7159,
and then UTF-8-encoding the resulting Unicode code points.
This means, for instance, that these payloads represented as JSON strings
are equivalent ("$.02", "\u0024.02").
Unassigned Unicode code point values MUST NOT be used to represent the payload.
It is intended that application profiles specify up front whether
b64 with a false value
is to be used by the application in each application context or not,
with it then being consistently applied in each application context.
For instance, an application that uses detached payloads might specify
that b64 with a false value
always be used.
It is NOT RECOMMENDED that this parameter value be dynamically varied
with different payloads in the same application context.
JSON Web Tokens (JWTs) MUST NOT use
b64 with a false value.
base64url-encodes the JWS Payload to restrict
the character set used to represent it to characters that are
distinct from the delimiters that separate it from other JWS fields.
Those delimiters are the period ('.') character for the JWS Compact Serialization
and the double-quote ('"') character for the JWS JSON Serialization.
When the b64 (base64url-encode payload)
value is false, these properties are lost.
It then becomes the responsibility of the application to ensure that
payloads only contain characters that will not cause parsing problems
for the serialization used, as described in ,
and that the payload will not be modified during transmission.
There is no security problem if a JWS correctly created using
b64 with a false value
is received by an implementation not supporting the b64
Header Parameter, since the signature will fail to verify
and the JWS will therefore be rejected.
Likewise, there is no security problem if a JWS is created by an implementation
not supporting this extension and received by an implementation supporting it,
since the JWS will not use the extension, meaning that the security considerations
are the same as for implementations supporting only the functionality specified
in .
The only case in which care may need to be taken is when a JWS is possibly being
received by a JWS implementation not supporting this extension and the party producing
the JWS might be an attacker that intentionally creates a JWS with a
b64 value of false
but signs it as if its value was true.
In this case, a JWS implementation not supporting this extension will accept the JWS
but treat it as if the payload was encoded, rather than unencoded.
While this confused case may seem like a problem that could matter, in fact,
if the recipient trusts the creator of a JWS based on its signature
and therefore accepts and acts upon the content in the JWS,
yet the creator is an attacker,
the recipient has much bigger problems than confusion between whether
the payload value is encoded or unencoded.
In this case, the attacker can sign any payload whatsoever
and have the recipient accept it --
including payloads designed to cause harm to the recipient.
If the trust established by verifying the signer's key does not actually
establish that the creator is a trusted party, then this case in which
JWS libraries supporting and not supporting the extension may respectively
interpret the attacker's payload as being encoded or unencoded is the least
of the application's worries.
This can only happen when the trust placed in the creator of the JWS is unfounded.
The other relevant perspective on this case is that if an application specifies
that JWSs used by it are to be created using
b64 with a false value,
per ,
then correct implementations of that application must use a JWS implementation
that implements this extension.
Thus, even malicious JWS creators intentionally incorrectly signing JWSs as if the
b64 value was false
cannot confuse the application as to whether the payload is encoded or unencoded,
since any incorrectly signed JWSs will be rejected due to the bad signature.
Only if the application is incorrectly implemented and doesn't support
this extension when the application requires its use, is a problem possible.
But then again, if the application is incorrectly implemented,
it likely has bigger problems than confusion about whether the payload is encoded or not.
Only if the application dynamically switches between
false and
true values for b64
(something NOT RECOMMENDED in ),
would it be necessary for the application to require the use of
crit with a value of ["b64"]
in such application contexts.
That would cause even incorrectly implemented application clients
that do not support the extension to nonetheless reject content signed using
b64 with a false value.
This specification registers the b64
Header Parameter defined in in
the IANA "JSON Web Signature and Encryption Header Parameters" registry
established by .
Header Parameter Name: b64
Header Parameter Description: Base64url-Encode Payload
Header Parameter Usage Location(s): JWS
Change Controller: IESG
Specification Document(s): of [[ this specification ]]
ASCII format for Network InterchangeUniversity California Los Angeles (UCLA)The Unicode StandardThe Unicode ConsortiumJSON Web Signature (JWS)Microsoftmbj@microsoft.comhttp://self-issued.info/Ping Identityve7jtb@ve7jtb.comNomura Research Instituten-sakimura@nri.co.jpJSON Web Algorithms (JWA)Microsoftmbj@microsoft.comhttp://self-issued.info/JSON Web Token (JWT)Microsoftmbj@microsoft.comhttp://self-issued.info/Ping Identityve7jtb@ve7jtb.comhttp://www.thread-safe.com/Nomura Research Instituten-sakimura@nri.co.jphttp://nat.sakimura.org/JSON Object Signing and Encryption (JOSE)IANAJSON Web Key (JWK)Microsoftmbj@microsoft.comhttp://self-issued.info/
Anders Rundgren, Richard Barnes, Phillip Hallam-Baker, Jim Schaad,
Matt Miller, Martin Thomson,
and others have all made the case
for being able to use a representation
of the payload that is not base64url-encoded
in contexts in which it safe to do so.
Thanks to
Sergey Beryozkin,
James Manger,
Axel Nennker,
Anders Rundgren,
Nat Sakimura,
Jim Schaad,
and
Matias Woloski
for their reviews of the specification.
[[ to be removed by the RFC editor before publication as an RFC ]]
-04
Corrected a typo in the JWS JSON Serialization example.
Added to the security considerations, including adding a statement about
when crit should be used.
Addressed the document shepherd comments.
-03
Allowed the ASCII space character and all printable ASCII characters
other than period ('.') in non-detached unencoded payloads
using the JWS Compact Serialization.
Updated the abstract to say that that the spec updates RFC 7519.
Removed unused references.
Changed the change controller to IESG.
-02
Required that b64 be integrity protected.
Stated that if the JWS has multiple signatures and/or MACs,
the b64 Header Parameter value
MUST be the same for all of them.
Stated that if applications use content encoding, they MUST specify
whether the encoded or unencoded payload is used as the JWS Payload value.
Reorganized the Unencoded Payload Content Restrictions section.
Added an "updates" clause for RFC 7519 because this specification
prohibits JWTs from using "b64":false.
-01
Removed the sph (secure protected header)
Header Parameter.
Changed the title to "JWS Unencoded Payload Option".
Added the section "Unencoded Payload Content Restrictions".
Added an example using the JWS JSON Serialization.
-00
Created the -00 JOSE working group draft from
draft-jones-jose-jws-signing-input-options-00 with no normative changes.