dvsekhvalnov / jose-jwt

Ultimate Javascript Object Signing and Encryption (JOSE), JSON Web Token (JWT) and Json Web Keys (JWK) Implementation for .NET and .NET Core
MIT License
921 stars 183 forks source link

JWT Nesting & Bloat #201

Open jxfreeman opened 1 year ago

jxfreeman commented 1 year ago

I am using jose-jwt to generate a nested (i.e. signed and then encrypted) JWT. The implementation is used to transfer large PDF files to a partner. As part of the specifications, a JSON request containing a Base64 encoded document (the PDF) is constructed. The JSON is then signed. This produces a Base64 encoded result which is then fed to encryption which yields a final Base64 encoded string. All told, the initial JSON is Base64 encoded 3 times. This results in a 137% increase in the token size. So a 9MB PDF turns into a 21.7MB token. So the nesting is either being done incorrectly or the library doesn’t have the appropriate features for doing something that seems somewhat standard in real world application.

Is there an example of nesting for jose-jwt in .NET and can it be done so that Base64 encoding can be done once at the end to avoid bloating?

dvsekhvalnov commented 1 year ago

Hi @jxfreeman ,

well, my best advice will be to take a look at https://github.com/dvsekhvalnov/jose-jwt#unencoded-and-detached-content-aka-rfc-7797 both follows RFC 7797. Allows you to skip base64 encoding and omit large binary payloads.

I'm not really sure what do you mean by nesting, are there any standard describing what you want to achieve?

P.S> i'd not use even original 9Mb PDF as payload personally :) it's definitely not what jwt have been designed for. Probably distributing it other way (S3, file shares, e.t.c.) and including only sha-256 hash in token can be better approach?

jxfreeman commented 1 year ago

Thanks for the quick turnaround! Nesting simply means signing then encrypting. I'm not versed on any RFCs for this practice just that I've read that it is common and one of the business partners for my firm requires that the JWT be signed and encrypted. I concur about using JWT for large payloads, but it was a partner requirement. Apart from the large payload, we use the non-optimal nesting approach for another API suite (from the same partner) and having the ability to optimally sign and encrypt would be useful; perhaps a feature request.

dvsekhvalnov commented 1 year ago

@jxfreeman well, RFC 7797 if your partner supports base64Mode=off is the best you can get.

Pretty sure you'll get pretty much same experience with any other library out there. There are no such thing as 'atomic-sign-then-ecrypt' in world of JWT (at least i'm not aware). The reason is authenticated encryption covers both confidentiality and integrity guarantees. Really no reason to sign it in a first place, i'm not even sure why people still doing it this way.

Smoovsky commented 1 year ago

Really no reason to sign it in a first place, i'm not even sure why people still doing it this way.

Agree, but there are still some standards out there that require a nested token to be generated: FAPI_JARM So that the issuer may have two separate sets of keys to handle signing and encrypting.

dvsekhvalnov commented 1 year ago

I don't disagree with it.

But still there is no any standard to solve original issues (bloating due to several base64 encodings in a row). Except Unencoded or Detached payload.