6 ms·
An easy enough mantra: sign bytes, not semantics. I've trudged through the bowels of SAML long enough to know that canonicalization is thoroughly tricky and ann
by andrewstuart2 7y ago
An easy enough mantra: sign bytes, not semantics. I've trudged through the bowels of SAML long enough to know that canonicalization is thoroughly tricky and annoying to deal with.
I don't care what you throw in the bytes; I can figure that out easily enough. I want to know who generated those bytes and that they haven't changed.
For this reason also, I think the "reach for symmetric first" is bad advice. The primary benefit I can think of for HMAC is if you want to store client-side state for more stateless browser-targeted services. It makes it easy to throw an obscure cookie to your client and then validate it on the way back. It seriously complicates things if you want to allow other people to validate provenance of those bytes. With symmetric crypto, as soon as you can validate you can also generate. That's not the system we want.
- lvh 7y agoYou say that's not the system you want but that's based on a pretty big "if": you need "someone else" to validate something, and those people can't talk to you directly and ask you if it's valid or not. That's not in practice how we see this being used. If you do need third parties to validate, a much simpler API is to just ask the thing that holds the HMAC credential over TLS, and have it return true/false. That makes it harder to demonstrate non-repudiation, but I'm not convinced that's a property you generally care about. Even in OIDC (which mandates a JWT, but for reasons that defy understanding doesn't mandate cryptographic domain separation between (IdP, RP) pairs), leading OIDC providers have long recommended you just talk to them over TLS to get userinfo. (GSuite has recently muddled this in their docs, which irks me.) (Disclaimer: I'm the author.)
- ysleepy 7y agoBut what about myself wanting to validate the payload on a system I don't necessarily trust? In the symmetric case I would grant that system the ability to sign.
- lvh 7y agoWhat's the model where you don't trust that system not to exfiltrate data but you do trust that system not to flip the boolean that says the signature is valid at all?
- ysleepy 7y agoSigning your updates for example. If the system is breached, theres nothing you can do, but that access does not translate to forging updates for other users.
- lvh 7y agoOh, sure, yes, absolutely, software updates is one of the cases where you probably just want an (asymmetric) signature. (And probably TUF.) But my alternative suggestion also addresses that: in a model where you don't trust the host with the key but you do need to help it make a determination if a particular thing is valid or not, you could just go ask the server you got it from instead. Basically: the key doesn't have to live on the machine doing the validation.
- tastroder 7y agoIf you get a malicious update from a compromised update server and then ask said server if the hash you got is correct, you might as well just roll a dice. You'd need a pinned certificate (e.g. for HTTPS) to prevent MITM and thus asymmetric crypto anyway.
- lvh 7y agoPartially yes. You don't need a pinned certificate, just working certificate validation. I am not suggesting you should never use asymmetric crypto: you should definitely use HTTPS. The question wasn't "is asymmetric crypto morally good or bad", it's "should I use asymmetric crypto in my code to do bespoke signing things". The asymmetric crypto in TLS is fine because you're not doing bespoke signing things: you're doing the most well-understood handshake + protocol on the planet.
- hirsin 7y agoEh? Got additional details on which OIDC providers aren't using a proper userinfo + AT? Not that that shouldn't include TLS... We don't do token introspection (basically what you're referring to) and instead use JWT/JWE(soon) to reduce round trips for the RP. Could you expand on the OIDC issue with cryptographic domain separation? Not sure I fully understand what benefits you're looking for there.
- lvh 7y agoRe: OIDC providers: to be clear, you absolutely can just parse the JWT. I'm saying that (up until recently, if memory serves) e.g. the GSuite documentation told you that while you can validate a token, that's hard, and instead you can just hit this HTTPS API and we'll tell you what's in it. (They seem to have flipped that in the last, I dunno, 3 months or so?)
- hirsin 7y agoAh, gotcha. That sounds like token introspection basically, which is a (budding?) standard, not really userinfo.
- lvh 7y agoUnless my memory is failing me, in the Google case it was really /userinfo (as in the OIDC Core UserInfo endpoint) and not token introspection (a "post-auth" endpoint taking a token, not a "pre-auth" one you pass a JWT to). Though I agree that from the perspective of a consumer the two are basically just as good :-)
- DenisM 7y ago> holds the HMAC credential over TLS, and have it return true/false And if you're connecting to the original party anyway might as well not even use HMAC or any crypto at all. When "signed" data needs to be sent to the client don't send it at all, instead store the data locally under a GUID and send that GUID to the client. When client takes their GUID to another party, that other party connects to the original party and retrieves perfectly authentic data. Free bonus - faster client performance. Best crypto is absence of crypto.
- SlowRobotAhead 7y agoSign bytes makes a lot of sense. But you’re still on your own for how that “should” be done. Obviously you need to build and hash the pairs and not just key values. But the order is obviously important too. Is there some standard for this I don’t know of?
- zdkl 7y agoSort the keys alphabetically usually comes up.
- SlowRobotAhead 7y agoHmm, interesting idea but I’m in embedded C. So that’s something I’d rather not do but I like the idea.
- blattimwind 7y agoYou generally don't need canonical representation.
- sk5t 7y agoIt's a good mantra--just not a wish that is applicable to the foundation of XML as a tree/document thing that self-describes its encoding and is capable of including its own signature within itself. I mean, it gets crazy complex, but the alternatives sort of require going on to some message format that isn't XML. One of the design goals of XML is that you could zip an XML document along through different systems, one of which supports only UTF-16LE, the next demands UTF-8, the next demands ISO-8859-1, and each could do the right thing. I mean, it's almost inconceivable that all the systems involved in such a quagmire would actually do the right thing, but they could, in theory. I'm sure you're already dreadfully familiar with this having looked at XML-DSIG. OTOH: base64(jsonString(envelope)) '.' base64(jsonString(claims)) '.' base64(sig) works fine for JWT, because JSON has a very much limited choice of encoding (one option, zero alternatives!) and a JWT has no requirement to still be JSON on both sides of the transformation. It's just an opaque 7-bit-safe string to any party that doesn't know what the contents are.
- munchbunny 7y ago> I don't care what you throw in the bytes; I do think whoever is coming up with the scheme for assembling those bytes should care a lot. Specifically, whenever you're signing something, you have to pay attention to whether that something still has exploitable ambiguities. Most of those come from how you delineate the fields in the thing you're signing, which is a classic "you find out what you missed when someone sends you a CVE" type of problem. So you're right back to the problem of "if not JSON or XML then you're still rolling your own." I agree with "reach for symmetric" in this sense: what are you trying to accomplish? Prove the data came from a specific source or that they are who they claim to be? Can you just use TLS with mutual auth? Prove the data came from yourself? Symmetric is probably okay. When you need verifiable attestations of data from parties that don't talk to each other... welcome to the jungle.
- rstuart4133 7y ago> canonicalization is thoroughly tricky and annoying to deal with. The bitcoin malleability problem was the same issue, just with ASN.1 instead of JSON.