flashman
← All guides

Canonical JSON for deterministic signatures and hashes

Create deterministic signed JSON with a defined canonicalization profile, exact byte encoding, safe numeric constraints, verification order, and fixtures.

2026-09-08 · 8 min read

  • json
  • cryptography
  • data-formats

JSON defines a data model and grammar, not one unique byte serialization. Equivalent objects can differ in member order, whitespace, escapes, number notation, and Unicode representation, so hashing an arbitrary serializer's output does not create an interoperable content identity.

A canonicalization profile defines one deterministic serialization for values inside its supported domain. It is useful only when every producer and verifier implements the same profile and signs the specified bytes.

Choose and name the profile

Use the canonicalization scheme required by the protocol, such as RFC 8785 when that is explicitly selected. Do not describe a home-grown combination of sorted keys and removed whitespace as canonical JSON without specifying every edge case.

  • Define accepted JSON value and numeric ranges.
  • Define UTF-8 conversion and malformed text handling.
  • Define member ordering and escape serialization.
  • Version the profile before changing any rule.

Constrain numbers and duplicate names

Different runtimes parse and render large integers, fractions, exponent forms, and negative zero differently. Reject values that the chosen profile cannot represent consistently, or model exact domain numbers as constrained strings.

Reject duplicate object member names before canonicalization. A parser that keeps the first value and one that keeps the last can sign or authorize different data from the same source text.

Keep cryptographic roles separate

Canonicalization provides deterministic bytes; a cryptographic signature or MAC provides integrity under a key. Verification still needs an authenticated algorithm and key selection, replay policy, authorization, and schema validation.

  • Bind protocol context to the signed message.
  • Encode signatures according to one declared format.
  • Compare authenticated values with maintained libraries.
  • Keep private keys and secret MAC keys out of browser tools.

Build cross-runtime conformance fixtures

Use Flashman's JSON formatter to inspect public values, diff for serialized bytes rendered safely as text, hash for fixture identifiers, Base64 for synthetic signature transport, and case converter to expose accidental field-name changes.

Test nested keys, empty containers, non-ASCII strings, escapes, numeric boundaries, exponent forms, negative zero, duplicate names, malformed Unicode, altered signatures, and every supported producer and verifier implementation.

Try these tools