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
