Open cyberphone opened 6 years ago
You may wonder what the purpose is, right?
Current standard for signed JSON: https://openid.net/specs/openid-financial-api-part-2.html#request
eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ew0KICJpc3MiOiA
(... abbreviated for brevity ...)
zCYIb_NMXvtTIVc1jpspnTSD7xMbpL-2QgwUsAlMGzw
JSON clear text signature alternatives depend on canonicalization:
{
"id": "johndoe",
"counter": 3,
"list": [
"yes",
"no"
],
"signature": {
"alg": "HS256",
"kid": "mykey",
"val": "rlKLoCBExrwB7NaChPtQ3cAxr83eGdpLA7txrg49slw"
}
}
End of Base64 tyranny 😂!!!
It's easy enough to do already during serialization, see e.g. OrderedContractResolver
from Order of serialized fields using JSON.NET when serializing a type using reflection.
Some additional effort would be required for dictionaries or dynamic objects though.
@dbc2 Yes, I took an updated version the stackoverflow sample (added StringComparer
which is compatible with the sorting algorithm)
public class Canonicalizer : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
return base.CreateProperties(type, memberSerialization)
.OrderBy(p => p.PropertyName, StringComparer.Ordinal).ToList();
}
}
for a scheme using declared objects but it failed for dynamic objects since the supplied contract resolver is never called (which may be logical since there is no contract).
Anyway, sorting alone does not enable signatures like above; serialization of JSON primitives must also conform to a standard and the only available such is specified in ECMAScript. Here is a 2000 line port achieving that: https://github.com/cyberphone/json-canonicalization/tree/master/dotnet/es6numberserialization
Hi, everyone! First of all, thanks for opening this issue, @cyberphone (and for the linked library).
I do believe adding a canonical formatter would be extremely helpful, specifically when trying to sign JSON files, and I agree that @cyberphone's suggestion of adding a new formatter in the enum.
@JamesNK - is this something we want to add in a future release? However, if that is not the case, what would be the best way to pass a custom formatter when serializing? (not a contract resolver).
This is a very useful formatting option for us to achieve deterministic output. Cloud Native App Bundle is also using Canonical JSON.
Is there any .NET library (Newtonsoft.Json or not) which supports Canonical JSON output? We're in desperate need of one :-)
Hi @drauch, here you have source for a variant of Canonical JSON: https://github.com/cyberphone/json-canonicalization/tree/master/dotnet The referenced specification is currently in the RFC publication queue.
Thank you for the recommendation.
Using canonicalization, it becomes very simple adding a digital signature to a JSON object: https://github.com/cyberphone/json-canonicalization/tree/master/dotnet/json.net.sign
I have skimmed the code and it "seems" that the least intrusive change would be to add one field to
Netwonsoft.Json.Formatting
.The suggested change would introduce the following algorithm: https://cyberphone.github.io/doc/security/draft-rundgren-json-canonicalization-scheme.html#json.sorting.properties
It would be sufficient calling this formatting mode
Sorted
since there are other things needed for full-blown I-JSON compatible signature support.