Remix.run Logo
tux3 2 days ago

JOSE/JWK is indeed some galactically overengineered piece of spec, but the rest seems.. fine?

There are private keys and hash functions involved. But base64url and json aren't the worst web crimes to have been inflicted upon us. It's not _that_ bad, is it?

unscaled 2 days ago | parent | next [-]

Yes, JOSE is certainly overengineered and JWK is arguably somewhat overengineered as well.

But "the rest" of ACME also include X.509 certificates and PKCS#10 Certificate Signing Requests, which are in turn based on ASN.1 (you're fortunate enough you only need DER encoding) and RSA parameters. ASN.1 and X.509 are devilishly complex if you don't let openssl do everything for you and even if you do. The first few paragraphs are all about making the correct CSR and dealing with RSA, and encoding bigints the right way (which is slightly different between DER and JWK to make things more fun).

Besides that I don't know much about the ACME spec, but the post mentions a couple of other things :

So far, we have (at least): RSA keys, SHA256 digests, RSA signing, base64 but not really base64, string concatenation, JSON inside JSON, Location headers used as identities instead of a target with a 301 response, HEAD requests to get a single value buried as a header, making one request (nonce) to make ANY OTHER request, and there's more to come.

This does sound quite complex. I'm just not sure how much simpler ACME could be. Overturning the clusterfuck that is ASN.1, X.509 and the various PKCS#* standards has been a lost cause for decades now. JOSE is something I would rather do without, but if you're writing an IETF RFC, you're only other option is CMS[1], which is even worse. You can try to offer a new signature format, but that would be shut down for being "simpler and cleaner than JOSE, but JOSE just has some warts that need to be fixed or avoided"[2].

I think the things you're left with that could have been simplified and accepted as a standard are the APIs themselves, like getting a nonce with a HEAD request and storing identifiers in a Location header. Perhaps you could have removed signatures (and then JOSE) completely and rely on client IDs and secrets since we're already running over TLS, but I'm not familiar enough with the protocol to know what would be the impact. If you really didn't need any PKI for the protocol itself here, then this is a magnificent edifice of overengineering indeed.

[1] https://datatracker.ietf.org/doc/html/rfc5652 [2] https://mailarchive.ietf.org/arch/msg/cfrg/4YQH6Yj3c92VUxqo-...

GoblinSlayer 2 days ago | parent [-]

>ASN.1 and X.509 are devilishly complex

Most of it is unused though, only CN, SANs and public key are used.

tialaramex 2 days ago | parent [-]

You really shouldn't need CN (but it's convenient for humans) however there are a bunch of other interesting things in the X.509 certificate, lets look at the one for this site:

Issuer: We need to know who issued this cert, then we can check whether we trust them and whether the signature on the certificate is indeed from them, and potentially repeat this process - this cert was issued by Let's Encrypt's E5 intermediate

Validity: We need to know when this cert was or will be valid, a perfectly good certificate for 2019 ain't much good now, this one is valid from early May until early August

Now we get a public key, in this case a nice modern elliptic curve P-256 key

We need to know how the signature works, in this case it's ECDSA with SHA-384

And we need a serial number for the certificate, this unique number helps sidestep some nasty problems and also gives us an easy shorthand if reporting problems, 05:6B:9D:B0:A1:AE:BB:6D:CA:0B:1A:F0:61:FF:B5:68:4F:5A will never be any other cert only this one.

We get a mandatory notice that this particular certificate is NOT a CA certificate, it's just for a web server, and we get the "Extended key use" which says it's for either servers or for clients (Let's Encrypt intends to cease offering "for client" certificates in the next year or so, today they're the default)

Then we get a URL for the CRL where you can find out if this certificate (or others like it) were revoked since issuance, info with a URL for OCSP (also going away soon) and a URL where you can get your own copy of the issuer's certificate if you somehow do not have that.

We get a policy OID, this is effectively a complicated way to say "If you check Let's Encrypt's formal policy documents, this certificate was specifically issued under the policy identified with this OID", these do change but not often.

Finally we get two embedded SCTs, these are proof that two named Certificate Transparency Log services have seen this certificate, or rather, the raw data in the certificate, although they might also have the actual certificate.

So, quite a lot more than you listed.

[A correct decoder also needs to actually verify the signature, I did not list that part, obviously ignoring the signature would be a bad idea for a live system as then anybody can lie about anything]

bostik a day ago | parent [-]

> You really shouldn't need CN (but it's convenient for humans)

Is this finally the case now? About 5 years back IIS would fail to load a certificate without a CN, despite the field being deprecated since 2000.

And who would run IIS? A bunch of janky/dodgy/shady marketing affiliates, at least. Quite common in the gambling industry.

tialaramex a day ago | parent [-]

I am definitely not telling you that it will work in all software, yeah. Only that it should work and well, that's not useful engineering advice.

oneplane 2 days ago | parent | prev [-]

I personally don't see the overengineering in JOSE; as you mention, a JWK (and JWKs) is not much more than the RSA key data we already know and love but formatted for Web and HTTP. It doesn't get more reasonable than that. JWTs, same story, it's just JSON data with a standard signature.

The spec (well, the RFC anyway) is indeed classically RFC-ish, but the same applies to HTTP or TCP/IP, and I haven't seen the same sort of complaints about those. Maybe it's just resistance to change? Most of the specs (JOSE, ACME etc) aren't really complex for the sake of complexity, but solve problems that aren't simple problems to solve simply in a simple fashion. I don't think that's bad at all, it's mostly indicative of the complexity of the problem we're solving.

unscaled 2 days ago | parent | next [-]

I would argue that JOSE is complex for the sake of complexity. It's not nearly as bad as old cryptographic standards (X.509 and the PKCS family of standards) and definitely much better than XMLDSig, but it's still a lot more complex than it needs to be.

Some examples of gratuitous complexity:

1. Supporting too many goddamn algorithms. Keeping RSA and HMAC-SHA256 for leagcy-compatible stuff, and Ed25519 for XChaChaPoly1305 for regular use would have been better. Instead we support both RSA with PKCS#1 v1.5 signatures and RSA-PSS with MGF1, as well as ECDH with every possible curve in theory (in practice only 3 NIST Prime curves).

2. Plethora of ways to combine JWE and JWS. You can encrypt-then-sign or sign-then-encrypt. You can even create multiple layers of nesting.

3. Different "typ"s in the header.

4. RSA JWKs can specify the d, p, q, dq, dp and qi values of the RSA private key, even though everything can be derived from "p" and "q" (and the public modulus and exponent "n" and "e").

5. JWE supports almost every combination of key encryption algorithm, content encryption algorithm and compression algorithm. To make things interesting, almost all of the options are insecure to a certain degree, but if you're not an expert you wouldn't know that.

6. Oh, and JWE supports password-based key derivation for encryption.

7. On the other, JWS is smarter. It doesn't need this fancy shmancy password-based key derivation thingamajig! Instead, you can just use HMAC-SHA256 with any key length you want. So if you fancy encrypting your tokens with a cool password like "secret007" and feel like you're a cool guy with sunglasses in a 1990s movie, just go ahead!

This is just some of the things of the top of my head. JOSE is bonkers. It's a monument to misguided overengineering. But the saddest thing about JOSE is that it's still much simpler than the standards which predated it: PKCS#7/CMS, S/MIME and the worst of all - XMLDSig.

oneplane 2 days ago | parent | next [-]

It's bonkers if you don't need it, just like JSONx (JSON-as-XML) is bonkers if you don't need it. But standards aren't for a single individual need, if they were they wouldn't be standards. And some people DO need these variations.

Take your argument about order of operations or algorithms. Just because you might not need to do it in an alternate order or use a legacy (and broken) algorithm doesn't mean nobody else does. Keep in mind that this standard isn't exactly new, and isn't only used in startups in San Francisco. There are tons of systems that use it that might only get updated a handful of times each year. Or long-lived JWTs that need to be supported for 5 years. Not going to replace hardware that is out on a pole somewhere just because someone thought the RFC was too complicated.

Out of your arguments, none of them require you to do it that way. Example: you don't have to supply d, dq, dp or qi if you don't want to. But if you communicate with some embedded device that will run out of solar power before it can derive them from the RSA primitives, you will definitely help it by just supplying it on the big beefy hardware that doesn't have that problem. It allows you to move energy and compute cost wherever it works best for the use case.

Even simpler: if you use a library where you can specify a RSA Key and a static ID, you don't have to think about any of this; it will do all of it for you and you wouldn't even know about the RFC anyway.

The only reason someone would need to know the details is if you don't use a library or if you are the one writing it.

folmar 2 days ago | parent | prev [-]

`cfssl` shows how easy could getting certificates signed be for the typical use case.

https://github.com/cloudflare/cfssl

lmz 2 days ago | parent | prev [-]

Imagine coming from JWK and having to encode that public key into a CSR or something with that attitude.

oneplane 2 days ago | parent [-]

Imagine writing your own security software when there are proven systems that just take that problem out of your hands so you don't need to complain about it.

lmz a day ago | parent [-]

I'm agreeing with you that the author is complaining too much. Going the other way they would probably go "and then we have to somehow encode the numbers '1 2 840 113549 1 1' somehow to mark the key type".