Here's a concrete example of something I find lacking in JOSE:
Here's a protected header encoded: eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19
And here it is decoded: {"alg":"HS256","b64":false,"crit":["b64"]}
The encoded string is 58 characters and the decoded is 42 characters. It uses UTF8 -> base64 -> ASCII to sign. Why not just use the UTF8 encoding?
Not only would unencoded messages be more human readable, but they would be smaller.
JOSE is JSON by technicality only. It breaks the JSON core tenant of human readability for no reason other than extra normalization.
It's not the best we have. The best we have in that category is any reasonable standardized signature format. Seriously, there is no need for a high-level message serialization format and a signature scheme to be related in any way.
Want an ancient but still okay standard (as long as the implementation used is decent)? Use PKCS #1 signatures. Want something spiffy and modern? Use Ed25519 or similar, standardized as RFC 8032. Want a scheme based on old and very well-tested technology? Use one of many hash-based signature schemes. (Be careful -- many are stateful and you can easily shoot yourself in the foot when signing a message.)
Okay, so you need an actual written standard for how to shove the signed data and the signature into a single blob. Fine, use PKCS #7, which has been published as an RFC since before a respectable fraction of HN readers were born. Or you could just encode a tuple of (data, signature) however you like, keeping in mind that the data needs to be just plain bytes at least until the signature is verified.
Need the header to encode which key to use to verify it? Fine, add a description of the key to the tuple and make absolutely certain when verifying that you have some reason to trust the key in question. Need algorithm agility? Fine, treat the algorithm as part of the public key.
Need all the other crap in JOSE? No, actually you don't need it because it's actively harmful.
(If you don't need an interoperable standard per se and just want code, use libsodium's crypto_sign_open. It works quite well and is pretty much foolproof, which is the whole point.)
Defining the "however you like" parts is the chief role of something like JOSE. Cryptographic standards like Ed25519 or ECDSA are not messaging formats. There needs to be an agreed way to send messages. That's the point of JOSE.
> so you need an actual written standard for how to shove the signed data and the signature into a single [...] you could just encode a tuple of (data, signature) [...] Need the header to encode which key to use to verify it? Fine, add a description of the key to the tuple [...] Need algorithm agility? Fine, treat the algorithm as part of the public key.
That's what JOSE defines.
There is no need for a special standard explaining with great verbosity how to glue existing standards that already fit together just fine. Especially when the standard tells you how to do it wrong as JOSE does.
For some reason people want a formal specification for everything, even when "N/A" is an applicable option here.