JSON canonicalization
Signatures and fingerprints need the same bytes every time. DID.is uses the JSON Canonicalization Scheme, RFC 8785, for:
- Data Integrity proofs (
eddsa-jcs-2022,ecdsa-jcs-2019); did:webvhSCIDs and entry hashes;- A2A agent card signatures;
- MCP tool fingerprints (
definitionSha256,schemaSha256).
The profile is reported as rfc8785-binary64-v1.
- Object members are sorted by their UTF-16 code units.
- No whitespace is emitted outside strings.
- Strings use the minimal escaping of RFC 8785 (
\b \t \n \f \r, lowercase\u00xxfor other control characters;/and non-ASCII are not escaped). - Numbers are IEEE-754 binary64 values serialized as ECMAScript does:
-0becomes0, exponents are used from1e21and below1e-6. - Integers beyond 253 − 1 round like in JavaScript:
9007199254740993becomes9007199254740992. Put large exact integers in strings.
Duplicate members are refused
Section titled “Duplicate members are refused”Different parsers handle duplicate object members differently: some keep the first, some the last. An attacker can use that to make a signer and a verifier see different values.
DID.is parses signed input strictly and rejects any duplicate member anywhere in the tree, after decoding escapes. For example, {"alg":"none","\u0061lg":"EdDSA"} is rejected with “duplicate JSON object member”.
Data Integrity hashing
Section titled “Data Integrity hashing”For the JCS cryptosuites, the signed data is:
SHA-256(JCS(proof options without proofValue)) || SHA-256(JCS(document without proof))The 64-byte result is verified against proofValue (multibase base58btc) with the key in verificationMethod.