by maple3142 on 2/9/25, 2:38 PM with 42 comments
by codeflo on 2/9/25, 7:45 PM
> Add the tag and the exact string you signed to the object, validate the signature and then validate that the JSON object is the same as the one you got.
In cryptographic practice, redundant information usually spells disaster, because inevitably, someone will use the copy that wasn't verified.
But let's dig into it. If I understand this correctly, the suggestion is to have something like this:
{
"object": "with",
"some": "properties",
"signatureInfo": {
"signedString": "{\"object\":\"with\",\"some\":\"properties\"}",
"signature": "... base64-encoded-signature ..."
}
}
It's mentioned that "the downside is your messages are about twice the size that they need to be". In my opinion, this scheme is pointless. To verify "the JSON object is the same as the one you got", you have to do what?1. Parse the outer object as JSON, extract and remove signatureInfo.
2. Verify the signature.
3. Parse the signedString as JSON.
4. Verify that the object you got in step 1 equal to object you got in step 3 using a some kind of deep equality.
First of all, this is error prone, and as underspecified as JSON is, there are potential exploits if the comparison isn't done carefully. But even worse, if you think about it, the outer JSON is entirely useless, since you need to parse the inner JSON anyway -- so why not just use it directly?
It seems to me that this suggestion is strictly worse than just sending the inner part:
{
"signedString": "{\"object\":\"with\",\"some\":\"properties\"}",
"signature": "... base64-encoded-signature ..."
}
Yes, it's no longer "in-band", but I don't think it was really in-band before, it was just out-of-band with an outer layer of redundant information.by treyd on 2/9/25, 5:18 PM
I don't think the protocol still injects the signature into event structures, but this weird "unsigned" field is still there looking at the source json for a message I sent today, but it's possible it's removed after processing and Fluffychat is just removing it.
by DarkUranium on 2/9/25, 4:58 PM
I know it's not the most elegant thing ever, but if it needs to be JSON at the post-signing level, why not just something like `["75cj8hgmRg+v8AQq3OvTDaf8pEWEOelNHP2x99yiu3Y","{\"foo\":\"bar\"}"]`, in other words, encode the JSON being signed as a string. This would then ensure that, even if the "outer" JSON is parsed and re-encoded, the string is unmodified. It'll even survive weird parsing and re-encoding, which the regex replacement option might not (unless it's tolerant of whitespace changes).
(or, for the extra paranoid: encode the latter to base64 first and then as a string, yielding something like `["75cj8hgmRg+v8AQq3OvTDaf8pEWEOelNHP2x99yiu3Y","eyJmb28iOiJiYXIifQ"]` --- this way, it doesn't look like JSON anymore, for any parsers that try to be too smart)
If the outer needs to be an object (as opposed to array), this is also trivially adapted, of course: `{"hmac":"75cj8hgmRg+v8AQq3OvTDaf8pEWEOelNHP2x99yiu3Y","json":"{\"foo\":\"bar\"}"}`.
by askvictor on 2/9/25, 8:28 PM
by lxgr on 2/9/25, 8:42 PM
Is "I want the server/validating side to be safe even against server-side attackers with read-only permissions" not a good reason? Because that's one thing that asymmetric signatures provide out of the box compared to MACs.
by monocasa on 2/11/25, 7:04 PM
Saying there's "sure there's lots of ways to serialize, but these specific rules get you the same octet and you sign that" is key to sanity in such situations.
For all of ASN.1's many sins, they got that part absolutely right.
by saurik on 2/9/25, 8:22 PM
https://docs.aws.amazon.com/amazonswf/latest/developerguide/...
by Zamicol on 2/9/25, 5:58 PM
by dang on 2/11/25, 10:45 PM
How not to sign a JSON object - https://news.ycombinator.com/item?id=20516489 - July 2019 (151 comments)
by hughes on 2/11/25, 5:58 PM
Does this imply that the application doesn't trust the transport/presentation layers?
by tgsovlerkhgsel on 2/11/25, 7:00 PM
Not just "OK". It's the only sane way to do it.
by Muromec on 2/9/25, 9:45 PM