14 ms·
How not to sign a JSON object
- nemo1618 7y agoI recall this plaguing the Secure Scuttlebutt project -- they were signing JSON objects that were encoded however Node saw fit to encode them, which meant that in order to write an alternative implementation of the protocol, you had to encode all the various objects exactly how Node encodes them, which is (unsurprisingly) non-trivial. I wonder if they addressed this in a later version.
- Vendan 7y agoAs one of the people that built a alternative implementation, this is completely true, but also much worse, cause there were 2 things around crypto, signing and hashing, and one encoded it one way, and the other encoded it a different way (encoding as far as utf16 and such) which meant that for ascii, everything just worked fine, but as soon as you started using non-ascii, everything got 2x as complex.
- tracker1 7y agoIf you're serializing the JSON, that is UTF8. You're signing UTF8 bytes... don't mess with them, and the signature will be the same... also, for JWT, the UTF8 is then converted to base64 representation and tethered to the signature. You're signing the UTF8 bytes, not JSON. It doesn't matter how it's serialized, if it isn't UTF8, you're doing it wrong. The order or properties doesn't matter, the signature is on the bytes.
- deleted 7y ago[deleted]
- Vendan 7y agoSSB signs objects like so: { "previous": "%XphMUkWQtomKjXQvFGfsGYpt69sgEY7Y4Vou9cEuJho=.sha256", "author": "@FCX/tsDLpubCPKKfIrw4gc+SQkHcaD17s7GI6i/ziWY=.ed25519", "sequence": 2, "timestamp": 1514517078157, "hash": "sha256", "content": { "type": "post", "text": "Second post!" } } gets signed like { "previous": "%XphMUkWQtomKjXQvFGfsGYpt69sgEY7Y4Vou9cEuJho=.sha256", "author": "@FCX/tsDLpubCPKKfIrw4gc+SQkHcaD17s7GI6i/ziWY=.ed25519", "sequence": 2, "timestamp": 1514517078157, "hash": "sha256", "content": { "type": "post", "text": "Second post!" }, "signature": "z7W1ERg9UYZjNfE72ZwEuJF79khG+eOHWFp6iF+KLuSrw8Lqa6 IousK4cCn9T5qFa8E14GVek4cAMmMbjqDnAg==.sig.ed25519" } which means that you have to be careful about how you remove the signature in order to verify the original. The "main" node implementation does this by parsing the json, removing the field, and then re serializing, forcing any alternate implementation to exactly match the node serialization in order to be compatible
- wyldfire 7y agoGee, I would just naively wonder whether the scope of the signature includes the outermost closing brace. Does it?
- Vendan 7y agoAt least when I implemented it, it was the full message, as a complete valid json object. The signature would get added as another field, and then the object reserialized.
- tracker1 7y agoThis is why JWT is better... JWT signs "header.body" with each part as base64 from the JSON, and joined with a period. The content in the body and header are immaterial.
- lvh 7y agoIt's not "better", it solves a materially different problem. The article already acknowledges that if you can afford to, you should just stick a tag on the outside. (That's what JWT does, but the actual thing recommended, just HMAC, is better still, for reasons mentioned elsewhere in the comments.)
- juliusmusseau 7y agoThe one approach you missed on that blog post: put an envelope inside an envelope. Does anyone ever do this? { "original":"json", "goes":"here" } Signed: { "original_json_contents_base64":"ewogICJvcmlnaW5hbCI6Impzb24iLAogICJnb2VzIjoiaGVyZSIKfQo=", "hmac_sha256_of_base64":"bf1f4cb95ce8633aff46888e1717873e32bb2a770b3d4b5b74a59e5e9adefeda" } This way you have full control over the raw bytes you want to sign (by forcing them into Base64 where other systems can't get their dirty paws on them). I guess the problem here is if intermediate systems want to do stuff based on the payload (but without validating it), they won't like this. But if the problem is just intermediate systems barfing on non-json, this might work! p.s. enjoyable blog post - as they always are! ;-)
- lvh 7y agoThat's true if you have the luxury of a traditional tag on the outside, but falls apart when you have systems where signatures are in-band, like SAML, which is where canonicalization shows up. (Both for UTF-8 itself, which isn't canonical, but especially for your serialization format e.g. XML/JSON, which is usually far hairier.)
- tracker1 7y agoIf you treat the original UTF8 as bytes, then you still have that as bytes... this is part of why JWT uses base64 around the JSON string's bytes. In any case, you don't create a signature on a string per se, you create it on bytes, even if those bytes are derived from a string. Also, you don't validate a signature by re-creating the bytes in question... that's a flawed approach, and not the approach for example JWT takes.
- lvh 7y ago> In any case, you don't create a signature on a string per se, you create it on bytes, even if those bytes are derived from a string. Everyone is on the same page that at some point bytes go into a hash function. That's not the problem. You mention JWT, but JWT only does external signing, which doesn't trigger the problematic case several people are describing to you. Perhaps an example would be more useful. If you start with a JSON like: {"a": 1} how do you build a JSON like: {"a": 1, "tag": "deadbeefdeadbeefdeadbeef"} with a signing and verification algorithm that works? > Also, you don't validate a signature by re-creating the bytes in question... that's a flawed approach, and not the approach for example JWT takes. Can you describe an HMAC validation process that doesn't involve recreating the bytes in the HMAC tag?
- tracker1 7y agoYou don't... you could create one like... {"body":"base64-json","tag":"hash"} It seems to me that trying to do what you're saying is a flawed approach.
- 7y ago
- steveklabnik 7y agoJSON is not always guaranteed to be UTF-8. It wasn't updated to mandate that until 2017 https://www.tbray.org/ongoing/When/201x/2017/12/14/RFC-8259-STD-90 https://www.tbray.org/ongoing/When/201x/2017/12/14/RFC-8259-... That said, I certainly hope that it is, generally speaking.
- tracker1 7y agoThe original spec said UTF-8/16/32, but unaware of any reference implementation that used anything other than UTF-8 ... though, who knows with hand rolled crap, and windows in the mix.
- Vendan 7y agohttps://tc39.es/ecma262/#sec-json.stringify https://tc39.es/ecma262/#sec-json.stringify The stringify function returns a String in UTF-16 encoded JSON format representing an ECMAScript value, or undefined.
- masklinn 7y agoPython's `json` returns text, which you can encode however you want.
- andrewstuart2 7y agoAn 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?
- kerblang 7y ago> Maybe you don’t need request signing? A bearer token header is fine If you're going to insist on symmetric key signatures, yeah. Otherwise a symmetric signature would be the same as using symmetric encryption to store user passwords, wouldn't it? You have to have the secret key to verify the user's signature.
- lvh 7y agoI don't understand your analogy. Can you elaborate? I don't see the parallel between (a)symmetric signatures and encrypting passwords.
- kerblang 7y agoThe article appears to say that you must sign your requests with a symmetric key. To verify the request, the server needs the same key, right? So the server needs a copy of every single user's encryption key. The server _could_ just store the keys plaintext in a database but I'm assuming we can agree that's a horrible idea. The best it can do is encrypt them symmetrically before storing them, using an extra-special secret key that needs to be protected very carefully. With username/password authentication, we don't store symmetrically encrypted passwords, do we? We store a one-way hash of the passwords instead, because symmetric is deemed not-good-enough.
- lvh 7y agoThe server is trying to validate that the thing it gets back is the thing it previously sent out, so that's a different model. What concretely are you suggesting we store as if it was a password? The serialized JSON object?
- kerblang 7y agoI'm beginning to think you're trolling, but... I'll make one last attempt to explain: How does the server verify the signature? Does it just wave a magic wand? Doesn't it need the same key the user used to sign the request?
- lvh 7y agoA super-awesome related project I didn't get a chance to work into this post (because it's entirely deserving of its own): https://github.com/benlaurie/objecthash https://github.com/benlaurie/objecthash To be clear: I think that's a niche use case and while I think ObjectHash does a great job of exploring it, I don't expect the median startup to need an ObjectHash implementation. (Disclaimer: I'm the author.)
- tialaramex 7y agoWhy is it _better_ to do tricky message processing before we achieve confidence that the message is legitimate/ genuine? Or is the argument that even though this is worse it's so useful we might really want to do it anyway?
- lvh 7y agoDefinitely authenticate first! If there's anything I said that made you think otherwise, let me know: I would like to amend that so no-one else thinks I could possibly mean that. The initially recommended (unless you can do otherwise) approach in the blog post is clearly "tag at the end" and every other approach also validates first. If you're referring to ObjectHash: like I said, it's a very niche application, I don't expect people to use it, and yeah, it enables new use cases. (I expect you'd still really be authenticating the ObjectHash somehow -- e.g. by sending it over TLS -- but that's out of scope for ObjectHash itself.)
- tialaramex 7y agoYes, I was referring to ObjectHash of course, since it's in the sub-thread about ObjectHash. "I don't expect people to use it" just seems like the sort of awful excuse you'd usually be jumping on people for. It's like someone built a github project with a bunch of crypto red flags to check whether their new "Search github for projects with crypto red flags" idea works. Don't get me wrong, it's clever, and I like clever. But I have learned in cryptography to only accept clever when it is clearly in the service of a specific pre-identified goal, and not just for its own sake. Isn't that normally a philosophy you'd subscribe to? What's the _pre-identified goal_ for this thing? While we're here, another red flag. Mentioning Certificate Transparency as a model for some other X Transparency. Certificate Transparency isn't a model for anything. People have been saying to themselves almost from the dawn of CT "Oooh, this is clever, I should do the same for X" and it's always a bad idea. Someone might need a Merkle Tree. I'd argue they shouldn't use ObjectHash anyway. But the chance they need all the other paraphernalia from CT? Basically non-existent.
- mixedCase 7y ago> Anyway, no, because you need to parse a header to read the JWT, so you inherit all of the problems that stem from that. Can anyone enlighten me what point is the author trying to make? JWT is pretty damn standard so it's my go-to for signing objects.
- lvh 7y agoWe should write the "The JWT Problem" post one day, but this post isn't that, so I really don't want to derail the discussion. The short version is that there are flaws in the JWT specification that make certain bugs likely. A classic example of the "you have to parse a header to use the JWT" problem is the HS256 vs RS256 confusion bug, where your JWT library would interpret an allegedly-HS256 (HMAC) JWT using RS256 (RSA) key material. The JWT would get validated using the public key of the RSA pair, interpreted as an HMAC key. But the public key is, you know, public! So the impact of the bug is that everyone can forge JWTs. That is not a problem that can happen in well-designed schemes. We do have a blog post from last year that tells you what we think you should do if you want to be safe and you know what kind of abstract thing (e.g. signing, MACing, etc) you need: https://latacora.micro.blog/2018/04/03/cryptographic-right-answers.html https://latacora.micro.blog/2018/04/03/cryptographic-right-a... (Disclaimer: I'm the author.)
- thegagne 7y agoI have a need to provide an update service where client software (that I control) can request download files, but any other clients cannot download the files. Currently using a terrible method with hashed query strings based on date, path, and a secret, which are then validated and have an expiration. Also, HTTP, so yeah it’s broken, but it at least prevents drive by scraping. At this point we have no need for assymetric (don’t need to identify the requester, just need to prevent spoofing). What method of securing would you recommend?
- lvh 7y ago1. Step one is HTTPS. Since you control the client, ideally just one ciphersuite. Maybe pinning? But given that it's HTTP now, maybe this this is running in a production environment that's hostile to good ideas? (Of course, plain HTTPS as usually configured doesn't authenticate the client.) 2. Step two is a bit more complex. I assume your clients hold the secret, know what path they want to hit, and compute the key that way? Tell me a bit more about the clients: what are they implemented in? What do they run on? Can you reliably ship updates? (I'd prefer to have this discussion here but if you can't discuss publicly I'd be happy to take a look. My contact info is in my HN profile.)
- Boulth 7y agoLooks good. I'm missing ACME request signing in comparison.
- baybal2 7y agoMore about use case than how to do it: client side certificate authentication is not a rocket science. Unless you 100% need to use signing for the use case like a client side ACL, there is genuinely no need to overengineer your web app with your own authentication scheme. But if your scale already mandates doing operations without server side ACL lookup for performance reasons, doing it over HTTP and web stack might already be inefficient by itself for the task.
- geofft 7y agoClient certs are great if you control the client. If, say, Slack told me that to use the Slack API I'd need to get a client cert, I would laugh. One thing that comes to mind is that either you have to check revocation on the server side, or you have to re-provision client certs frequently, and in most client libraries that's actually difficult / annoying. If the server just sends me an updated token, I can just put that in a local variable and call it done. There's a reason most APIs have moved to "you can just put the token in the request payload". It's hard enough to ask people to set HTTP headers, asking them to set client certs will be super complicated.
- baybal2 7y ago> in most client libraries that's actually difficult / annoying. You can add a client cert with just 2 clicks on Windows. To my experience, that's way easier than most API authentication schemes
- geofft 7y agoOne, on Mac and Linux it's more involved. Two, I'm talking about client libraries, not web browsers. Every client library (including those used by web browsers) is perfectly capable of passing a query parameter. Most can pass cookies or custom headers. Not all of them can pass client certs.
- EGreg 7y agoSeems that you just need to go ahead and build a canonical JSON encoder in JS. It would be slower but hey, you need the same consistent algorithm for signing. The encoder would be part of the spec.
- lifthrasiir 7y agoThe OP notes that there are multiple competing (well, probably?) specifications for a canonical JSON and they are annoying to implement. JSON is neither well-designed nor well-specified [1] and it is likely that we will never see the official canonical JSON format anyway. [1] http://seriot.ch/parsing_json.php http://seriot.ch/parsing_json.php
- tracker1 7y agoJSON is UTF8, it's already canonical in that regard, if you don't f*ck with the serialized bytes tethered to the signature, you'll be absolutely fine.
- lvh 7y agoNot in the sense that the term of art "canonical", as in canonicalization, is used. UTF-8 is not canonical: different byte sequences can map to identical meanings, as covered in the post.
- tastroder 7y agoI'm really confused by some of the assumptions in this whole thread, sorry. In what scenario would a client touch the string it authenticates and parsed JSON from before sending it back to the server later? This argument seems to assume that I have to throw away the string I've parsed or somehow reconstruct the same JSON and create the HMAC myself locally, which seems odd.
- lvh 7y agoI think I may have answered your confusion in a different thread (I'm not sure I parsed your comment correctly though), but: this is about a problem that specifically occurs when you have JSON (or some other structured format) that needs to have the signature in-band. You're right that it's way easier (the first list of three bullet points, as you mentioned inthe other comment thread) if you can just shiv the tag on the outside. Perhaps a more familiar case where this happens is SAML assertions with inline signatures?
- beefhash 7y agoI'd go one step further: If you're in the situation that allows for HMAC over asymmetric signatures, you might as well go all the way with authenticated encryption instead of purely a MAC. Even if you have TLS, you still gain a minor benefit of having black box tokens to everything outside the system, in particular if you have to let untrusted or semi-trusted clients hold on to signed data that they needn't know the contents of. Yes, security through obscurity is not sufficient on its own, but can help stall analysis and exploitation efforts,
- lvh 7y agoI don't think that addresses the problem set out in the post. Other, non-cooperative third-party systems need to be able to parse the JSON blob as is.
- notJim 7y agoI'm sort of skeptical of the idea that a bunch of people hand-rolling HMAC stuff is going to contain fewer security issues in the long term than widely-used, tested JWT libraries. Sure if they do exactly what you say here, and nothing else, that might work. But what happens when they realize they need some minor tweak to it…
- tracker1 7y agoBeyond that, hand-rolling JWT isn't so hard at all. When I read about some of the exploits in certain libraries, I didn't have to worry about it, as I only supported the known authority's public key in the system I was working on. Of course, that makes the header effectively useless in practice.
- lvh 7y agoIf you write your own library to do it, there are strictly more things that can go wrong because at some point you're implementing a HMAC validation thingy. If you use a third party library, you're exposed to bugs that stem from JWT's design flaws even if you only allow a specific key, like the RS256 v HS256 bug I mentioned. You are definitely right that if for some reason you must do JWT, the way to do that is to strip as much of it away as possible. In particular, if you wanted to do safe HS256-only, you'd ignore the header, decode the body and tag, and validate the tag.
- tracker1 7y agoTo be clear, I didn't write a cryptography library... I wrote a JWT wrapper for validating JWT for the system in question. This was also before there were JWT libraries for a number of platforms. Beyond all of this, the JWT validation worked across a number of tokens generated from an alien (to the app in question) application, and rejected when it didn't validate. Also, it was literally only validating the tag and ignoring the header... it was using an asymmetric key for signing
- tptacek 7y agoThere are two obvious problems with this approach to engineering: 1. You don't know what you don't know, and there is a lot to know about cryptography beyond the minimum needed to interoperate with other systems. 2. If you're engineering seriously, you know people are going to inherit your code and your design down the road, and if you're relying solely on a minimal feature set without a coherent, informed design, those people are building on sand. Rolling your own JWT is a bad plan.
- mikepurvis 7y agoIt's not JSON, but I had a scenario like this where I wanted an in-band checksum on an archive of files. In the end it was indeed a file with the signature included in the archive itself, and the formula for computing it was basically the shasum of the shasums of `file .` sorted alphabetically, with the signature file itself excluded. That worked out just fine, but I can see the argument that it's much harder to get to a canonical JSON representation than it is to get to a canonical "tree of files" representation. Indeed, it was easy enough in my case that the repo contained a shell script one-liner that would compute it, and that was the reference against which the "real" python implementation was validated.
- lvh 7y agoThat sounds like you found an alternative format where finding something canonical to sign is easy (files, the shasum CLI) and punted on canonicalizing the in-band signature (which is good!).
- tracker1 7y agoI actually prefer JWT with an asymmetric key. Anyone can confirm the payload's providence. HTTPS takes care of encryption for the payload. Of course with JWT, only allow trusted keys or signed keys from a trusted CA. There have been some poor implementations, but the method is pretty sound.
- dev_dull 7y agoIt's amazing to me that the whole article glosses over issues around key storage for symmetrical encryption, not to mention now you have an O(n) liability issue with all of your readers.
- tracker1 7y ago+1 on this. With asymmetric signing, you don't have to spread a secret far and wide. You could go a step farther with client certs, but still would need a more heavy management interface and a CA setup against your applications which means quite a bit more complexity.
- lvh 7y agoThe set of readers is of cardinality one in the scenario described.
- geofft 7y agoI think the scenario they're envisioning is one where the server generates an object, and some time later, wants to make sure it's getting back an object that the server has previously generated. HTTP cookies are a good example of this. Anything where you'd reach for JWT is probably also this use case. > his post is mostly about authenticating consumers to an API. ... you’re trying to differentiate between a legitimate user and an attacker, usually by getting the legitimate user to prove that they know a credential that the attacker doesn’t. The recipient of the API key doesn't need to verify their object. There's no attack from being able to give someone a fake API key - any attacker in a position to modify the API key in transit, which would just be a DoS, is also in a position to drop the connection, which is also a DoS. Such an attacker is probably also in a position to steal the API key silently, which is a bigger problem. (If a client is really curious whether they have a valid API key, they can just make an API call with it and see if it works, they still don't need to actually check the signature.)
- closeparen 7y agoI don’t think that’s a fair assumption. Google IAP puts JWTs in headers to attest the end user’s identity in a way you can’t just forge from inside the firewall. Other use cases have you obtain a JWT from a dedicated auth service, maybe even a 3rd party provider, so that other random services don’t have to know about passwords and 2FA. In both cases it would be prohibitively expensive to call back to the auth service to verify each token. The point of using a standard like JWT is to make it intelligible in other codebases, otherwise you could make your own format and serialization.
- jiveturkey 7y agoA fatally flawed post that dooms it to the category of SEO rather than what should be useful information. I did especially like: > Canonicalization is a quagnet, which is a term of art in vulnerability research meaning quagmire and vulnerability magnet. You can tell it’s bad just by how hard it is to type ‘canonicalization’. The flaw? There's nothing here not already well known, so this isn't an insightful piece for those already well versed. Therefore, this is a piece written for those that aren't so practiced, for the sake of discussion: junior dev or devops, or non-security devs. The content itself is a good discussion, and digestible (lol). But, as a piece that junior folks are expected to get a takeaway from, the introduction is a disaster: > This post is mostly about authenticating consumers to an API. ie, not service-to-service auth. > Unless you have a good reason why you need an (asymmetric) signature, you want a MAC. A MAC/HMAC requires the signer and all verifiers to have the key. As stated just prior, this is about "frontend" signing. A novice reader might not realize they have to guard the key very well, and might even send it to the client browser. "Unless you have a good reason" is not a sufficiently strong warning for a post that is written as an instructable, more or less. More architectural introduction (bonus with diagrams) is required. As is, this post is a footgun.
- tastroder 7y agoNot sure why you are downvoted, about 10% of the article addresses it's headline and I frankly do not get the point either. The proposed solution is in the first numbered list and between that and the conclusion list is a bunch of prose on non-JSON payload. The only slightly JSON related content in there is a constructed scenario for 'in-band' signatures (the regex thing) which can just as well be achieved by a bit of string processing. Any JSON object will start with {, end with } and have some more information between it. Replacing the initial curly brace with '{"hmac": "foo",' gives you a valid JSON document. You can remove that easily before parsing and place no restrictions on the object's keys. You can handle edge cases like JSON literals or arrays by wrapping the whole thing in {"hmac": "foo", "payload": yourstring} if you feel like it.
- lvh 7y ago> Not sure why you are downvoted, about 10% of the article addresses it's headline and I frankly do not get the point either. The proposed solution is in the first numbered list and between that and the conclusion list is a bunch of prose on non-JSON payload. The proposed solution is not in the numbered list. The numbered list describes how to sign a JSON blob from the outside. The rest of the doucment describes what you do if that's not an option, and you need to sign the blob in-line. The very next paragraph after said numbered list describes how to do that. (I'm the author.)
- HONEST_ANNIE 7y agoHowto prove you are a God: Create a json file {"msg":"I am a God. My name is Bob.", "sha256":"78A873E..."} where the hash is the checksum of the file including the checksum. It would be equal to finding fixed point in cryptographic hash function that happens to be checksum to your message.
- geofft 7y agoThat's pretty easy to do with MD5 :) https://twitter.com/i/moments/838685002703466497 https://twitter.com/i/moments/838685002703466497
- dmitrygr 7y ago> Canonicalization is fiendishly difficult. 1000 times this! If you think you need canonicalization, always remember: "no you do not!" It is not a hill you want to die on.
- neilv 7y agoWhile integrating with a large company's SSO protocol (with a cleanroom implementation), I found that the off-the-shelf "standard" XML DSIG canonicalization code they were using (from a major vendor) actually was not compliant with the W3C spec. That was unpleasant to have to discover and then explain.
- k__ 7y agoWhat's the issue with it? I read, some GraphQL caching implementations relon canonicalization.
- eridius 7y agoThe "regex bait and switch trick" doesn't work if any of the intermediate processors might decode and re-encode the JSON.
- lvh 7y agoThat's an excellent point, you're of course right and the blog post could do a better job explaining that. I'll amend.
- deleted 7y ago[deleted]
- forgotmypw3 7y ago> Canonicalization is a quagnet, which is a term of art in vulnerability research meaning quagmire and vulnerability magnet. You can tell it’s bad just by how hard it is to type ‘canonicalization’. The funniest line from this article and my word of the day.
- lvh 7y agoThat one is all 'tptacek.
- timemachine 7y agoA fun read and primer on the subject. However, I would like to see more emphasis on including a time stamp as part of the signed payload. The reason is multifold: (a) Most importantly prevents ‘replay attacks’ [1]. Systems that need to send send the same command will do so with a unique time stamp and, therefore, a unique signature. (b) The time stamp + signature is an idempotency key. Your key cache’s TTL is the same as the timeout for your time stamp rejections. (c) To a lesser extent bolsters the system against a brute force length extension attack (see the Flickr API flaw in the reading) by reducing the time the middle-man has to correctly calculate the glue bytes. 1: https://en.wikipedia.org/wiki/Replay_attack https://en.wikipedia.org/wiki/Replay_attack