TL;DR: Removing the scaling limitation to make JOSE broadly applicable (by 
incurring any 33% overhead of base64url-encoding outside the crypto 
calculation) is a compelling reason to accept a cost of a few dozen additional 
lines of code in binary-unfriendly languages.


>> #23: Make crypto independent of binary encoding (base64)
>>
>> The cryptographic operations that JOSE performs should not depend on the  
>> transfer encoding used for binary components.  The operations should work  
>> directly on the encoded byte strings, not on the encoded form.


Thanks for adding this issue Richard.

The reason this can work for the JWE JSON serialization is that the separate 
segments (protected header, IV, plaintext) are passed as separate arguments to 
the AEAD algorithm (AAD, IV, plaintext). Each AEAD algorithm ensures there can 
be no confusion between the arguments.

AES_CBC_HMAC_SHA2, for instance, includes the length of the AAD in its HMAC 
calculation: HMAC(AAD || CIPHERTEXT || LENGTH(AAD)).

AES256GCM, for instance, calculates its authentication tag as GHASH(AAD || 
padding || CIPHERTEXT || padding || LENGTH(AAD) || LENGTH(CIPHERTEXT))

Signing & MAC algorithms accept a single argument for the content to be signed, 
whereas JWS wants to sign two fields: header & payload. So JOSE needs to 
specify how the header and payload are combined.

A good solution for JOSE would be to follow the example of these AEAD 
algorithms. For instance, specify that the bytes to be signed are HEADER || 
PAYLOAD || LENGTH(HEADER), where HEADER is the UTF-8 encoded header JSON 
object. 


> 1.       Use  length prefix on each field – this is the ASN.1 encode it 
> version
> 2.       Use fields that are well defined in terms of delimiters
> 3.       Put in separation characters which are not allowed in either field.
> 
> I once tried to argue that this is what we should do and ended up with the 
> following:  Method one was not considered acceptable, method two was not 
> possible given the current state of JSON parsers, method three is what we 
> currently do.


We should reconsider a variant of option 1 (include the length of the header at 
the end).

Applying crypto (eg HASH or ENC/DEC) to a base64url encoding means there will 
always be a 33% overhead. Applying it to a concatenation of bytes plus a length 
field means there is a fixed overhead (eg 8 bytes). Both can be ignored for 
small messages. A 33% overhead will be a showstopper for large messages.

Small messages is a primary use case for JOSE today. Without being able to 
scale efficiently though, we are crippling its wider applicability. There would 
be ongoing pressure to use something other than JOSE whenever a protocol might 
handle messages that are medium-sized or larger.

The downside of not signing the base64url-encoding is that JOSE libraries need 
to handle bytes, instead of strings, in a few more places. That will add some 
work in some binary-unfriendly languages. My guess is that the extra work is of 
the order of dozens on lines of code. Removing the scaling limitation to make 
JOSE broadly applicable is a compelling reason to accept that extra work.

--
James Manger
_______________________________________________
jose mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/jose

Reply via email to