Re: [jose] #26: Allow for signature payload to not be base64 encoded

Richard Barnes <rlb@ipv.sx> Tue, 02 July 2013 22:25 UTC

Return-Path: <rlb@ipv.sx>
X-Original-To: jose@ietfa.amsl.com
Delivered-To: jose@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 76D5611E8114 for <jose@ietfa.amsl.com>; Tue, 2 Jul 2013 15:25:35 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -0.973
X-Spam-Level:
X-Spam-Status: No, score=-0.973 tagged_above=-999 required=5 tests=[BAYES_00=-2.599, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-1, TRACKER_ID=2.003]
Received: from mail.ietf.org ([12.22.58.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dPB2rEXoRI8V for <jose@ietfa.amsl.com>; Tue, 2 Jul 2013 15:25:31 -0700 (PDT)
Received: from mail-oa0-f42.google.com (mail-oa0-f42.google.com [209.85.219.42]) by ietfa.amsl.com (Postfix) with ESMTP id D5DAF11E8110 for <jose@ietf.org>; Tue, 2 Jul 2013 15:25:26 -0700 (PDT)
Received: by mail-oa0-f42.google.com with SMTP id j6so7236124oag.15 for <jose@ietf.org>; Tue, 02 Jul 2013 15:25:24 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-originating-ip:in-reply-to:references:date :message-id:subject:from:to:cc:content-type:x-gm-message-state; bh=YqCL9nG5vpbCU1A/yCLZiEcvLNhATL/sGP+QjVjGBw4=; b=QRamrqfkOKyD+g0bIfdY6LeDvg6rnLu9ZJwAAnEiG/KE5rtflSsrpKEiCqw7vNoTc8 6S7FjoSQ8gths4Ymlq2zxo3NdSGk4DIeQTQjjZlmtt2m9SK9Kyj26ue4v7UJP5HHFNqm yNZeoST6u226EimFIFNAmvXrM7Tiduh/VnhbSKv0KzbmKs/qGkEUqrYCCzdOUCSNDPuD r3K2cnl1Wy9escGrtEvu+zR2paYuklsvIDvH6ivz+2d9suXBdfMSj/X76Rg/LOc14NbB mWD9cgnPeHhFSxswpRVlR2tGjCuELbhI7BpGD8amT+Tz8Z5Hkjt65wmKLs6OcJtMPpmO kgvw==
MIME-Version: 1.0
X-Received: by 10.182.142.104 with SMTP id rv8mr14481856obb.3.1372803621616; Tue, 02 Jul 2013 15:20:21 -0700 (PDT)
Received: by 10.60.26.135 with HTTP; Tue, 2 Jul 2013 15:20:21 -0700 (PDT)
X-Originating-IP: [108.18.40.68]
In-Reply-To: <CAD9ie-sBGnv5QbjFeQiXiMJ0Git06LPsAkoNeN7KZxRNqukv3w@mail.gmail.com>
References: <061.c2fcfec0a75d48eb8b194991ce56157e@trac.tools.ietf.org> <076.3f5d1244c042cd87bfb07814924fcbc9@trac.tools.ietf.org> <033a01ce729b$26bc3910$7434ab30$@augustcellars.com> <51CBA981.4050006@nri.co.jp> <048f01ce7355$19f05bc0$4dd11340$@augustcellars.com> <4E1F6AAD24975D4BA5B1680429673943678A0114@TK5EX14MBXC283.redmond.corp.microsoft.com> <04bf01ce7359$5ab862c0$10292840$@augustcellars.com> <CAL02cgTkUrQptGqOfQyhCembS1e3Qxw3peRFnO5QjswUW=XR-w@mail.gmail.com> <CAD9ie-sZ+w_HADMTnnkTC8XRJmjZvwYOmA+AhvJGTNPhhK=Z4g@mail.gmail.com> <CAL02cgQbAQ8zhumdR_uvXjhbZM0iXpfPnmgcJrMUuh4+bj11NA@mail.gmail.com> <CAD9ie-sBGnv5QbjFeQiXiMJ0Git06LPsAkoNeN7KZxRNqukv3w@mail.gmail.com>
Date: Tue, 02 Jul 2013 18:20:21 -0400
Message-ID: <CAL02cgSFjiBUECdUoVbArdszRCPgsfLX_Yr11zDUjrrX3RTPaw@mail.gmail.com>
From: Richard Barnes <rlb@ipv.sx>
To: Dick Hardt <dick.hardt@gmail.com>
Content-Type: multipart/alternative; boundary="001a11c2eaae36a34d04e08ec009"
X-Gm-Message-State: ALoCoQmlHuX50Zu/nxM4k0TnyQnSEW3gb/oF4f5r+FBGujXU2qd8J3Bv/j9UhVUxrBvLrK32TMzH
Cc: Jim Schaad <ietf@augustcellars.com>, n-sakimura <n-sakimura@nri.co.jp>, Mike Jones <Michael.Jones@microsoft.com>, "jose@ietf.org" <jose@ietf.org>, "draft-ietf-jose-json-web-signature@tools.ietf.org" <draft-ietf-jose-json-web-signature@tools.ietf.org>
Subject: Re: [jose] #26: Allow for signature payload to not be base64 encoded
X-BeenThere: jose@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: Javascript Object Signing and Encryption <jose.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jose>, <mailto:jose-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/jose>
List-Post: <mailto:jose@ietf.org>
List-Help: <mailto:jose-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jose>, <mailto:jose-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 02 Jul 2013 22:25:35 -0000

Glad that helped.  Detailed examples below.

Couple of high-level points to help the examples make sense:
1. Define a "cenc" header parameter, for "Content ENCoding", with one
value, "b64u".  When present in the JSON serialization, the "payload" field
is base64url encoded; when it is absent, the "payload" field represents the
payload directly (as a UTF-8 string).
2. For the compact serialization, "cenc" is always "b64u".
3. When protected a header are present (always for the compact
serialization), the JWS Signing Input is base64(protected).base64(payload),
as it is in -11.  When no protected header is present, the JWS Signing
Input is simply the octets of the payload.

With that in mind, let's look at a few test cases.  We'll use the following
inputs:

Header: {"alg":"HS256","kid":"2"}
== 7b22616c67223a224853323536222c226b6964223a2232227d (hex UTF-8)
== eyJhbGciOiJIUzI1NiIsImtpZCI6IjIifQ (base64 UTF-8)

Key (kid=2): 0x0001020304050607 (8 octets)

Payload: "café"
== 636166c3a9 (hex UTF-8)
== Y2Fmw6k (hex UTF-8)

With those inputs, let's consider 4 cases that show the possibilities
discussed above.

### CASE 1: Compact / protected / b64u

eyJhbGciOiJIUzI1NiIsImtpZCI6IjIifQ
.Y2Fmw6k
.QUoMVpjxLXjH1ZAX9tw4QEPnL6G_Hvd4EjD-JsHilyk

No change here.  The compact case just represents the special case where
the payload is base64-encoded and all the headers are protected.  Thus, we
use the base64.base64 form for the JSON Signing Input.
JWS Signing Input: eyJhbGciOiJIUzI1NiIsImtpZCI6IjIifQ.Y2Fmw6k (as a UTF-8
string)
== 65794a68624763694f694a49557a49314e694973496d74705a434936496a496966512e5932466d77366b
(hex)

### CASE 2: JSON / protected / b64u

{
  "unprotected":{"cenc":"b64u"},
  "protected":"eyJhbGciOiJIUzI1NiIsImtpZCI6IjIifQ",
  "payload":"Y2Fmw6k",
  "signature":"QUoMVpjxLXjH1ZAX9tw4QEPnL6G_Hvd4EjD-JsHilyk"
}

This is just the JSON equivalent to Case 1.

### CASE 3: JSON / unprotected / b64u

{
  "unprotected":{"alg":"HS256","kid":"2","cenc":"b64u"},
  "payload":"Y2Fmw6k",
  "signature":"X-GwEVfz9WEi0UhrmK1muKXecqxMipngSL_ZenXw5Lo"
}

Here we've removed the integrity protection from the headers (because who
needs it? ;) ).  So the signature is different, because JWS Signing Input
here is just the payload.
JWS Signing Input: café (as a UTF-8 string)
== 636166c3a9 (hex)

### CASE 4: JSON / unprotected / plain

{
  "unprotected":{"alg":"HS256","kid":"2"},
  "payload":"café",
  "signature":"X-GwEVfz9WEi0UhrmK1muKXecqxMipngSL_ZenXw5Lo"
}

This object is equivalent to Case 3, but with the payload expressed
directly as a JSON string instead of base64-encoded.  And, if you ask me,
the prettiest and most human-readable of the whole menagerie here :)

I've written a script to generate these test cases, in case you want to
play with this some more:
<http://test.polycrypt.net/temp/hello-jose.html>

Hope this helps,
--Richard


On Fri, Jun 28, 2013 at 7:04 PM, Dick Hardt <dick.hardt@gmail.com> wrote:

> Hi Richard, that helps.
>
> Our you looking at a way of effectively signing a JSON payload? A
> complete, real world example would help alot.
>
>
> On Fri, Jun 28, 2013 at 3:57 PM, Richard Barnes <rlb@ipv.sx> wrote:
>
>> Hey Dick,
>>
>> I guess I should have been clearer that I was only talking about the JSON
>> serialization.  My proposed change would have no impact on the compact
>> serialization.  Hopefully that answers your questions about separators,
>> etc.; they payload would just be a normal JSON string.
>>
>> --Richard
>>
>>
>> On Thu, Jun 27, 2013 at 7:56 PM, Dick Hardt <dick.hardt@gmail.com> wrote:
>>
>>>
>>>
>>>
>>> On Thu, Jun 27, 2013 at 3:24 PM, Richard Barnes <rlb@ipv.sx> wrote:
>>>
>>>> I think there are two separable issues here, both of which Mike and I
>>>> probably have divergent opinions on :)
>>>> 1. Syntax: Should it be possible for the "payload" field JWS to be a
>>>> JSON string (instead of base64) when the payload is simply a UTF-8 string?
>>>>
>>>
>>> One of the goals of the token was that it not require encoding for it to
>>> be transported in a request. IE that it be safe and SIMPLE to include in an
>>> HTTP header or in a URL
>>>
>>>
>>>> 2. Crypto: Must the JWS Signing Input be base64url encoded.
>>>>
>>>> The current answers to these questions are:
>>>> 1. It is not possible.  Payload is always base64url encoded.
>>>> 2. It is always base64url encoded.
>>>>
>>>> The answers should be:
>>>> 1. The payload should not be base64url encoded unless it cannot be
>>>> represented as a JSON string.
>>>>
>>>
>>> How does an implementation determine which parts are separated? Are '.'
>>> escaped? Does the implementation need to parse the JSON to determine a
>>> valid separator? How does it know the end of the JSON? That sounds really
>>> hard to implement, or I am misunderstanding what you are proposing.
>>>
>>>
>>>
>>>> 2. The JWS Signing Input should not be base64url encoded unless there
>>>> is a JWS Protected Header
>>>>
>>>> Neither of these are complicated changes:
>>>> 1. Add a "b64" header parameter that indicates that the payload is
>>>> base64url-encoded binary, as opposed to a UTF-8 string.  Specify that this
>>>> parameter is on by default in compact-formatted JWS objects.
>>>>
>>>
>>> And how is the header separated from the payload?
>>>
>>>
>>>>  2. Modify the signing/verification instructions to switch based on
>>>> the presence of a JWS Protected Header: "If the JWS Protected Header is
>>>> absent or empty, then the JWS Signing Input is simply the JWS Payload (not
>>>> encoded).  If the JWS Protected Header has a non-empty value, then the the
>>>> JWS Signing Input is the concatenation of the Encoded JWS Header, a period
>>>> ('.') character, and the Encoded JWS Payload"
>>>>
>>>> There are two reasons for these, both of which are important to make
>>>> sure that this spec is applicable to a broad variety of use cases:
>>>> 1. Compactness.  As Jim notes, quoted strings are shorter than
>>>> base64url-encoded strings
>>>>
>>>
>>> The tokens are already compact enough.
>>>
>>>
>>>>  2. Crypto-compatibility: Avoiding base64-encoding means that there's
>>>> nothing JWS-specific about the signature value.  So for example, you could
>>>> translate a JWS with no protected attributes to a CMS SignedData object
>>>> with no protected attributes.
>>>>
>>>
>>> Not a useful feature from my point of view.
>>>
>>> -- Dick
>>>
>>
>>
>
> _______________________________________________
> jose mailing list
> jose@ietf.org
> https://www.ietf.org/mailman/listinfo/jose
>
>