GxP Seal ← gxpseal.com

Verification

Verify a signature certificate.

A GxP Seal certificate is self-verifying: it carries the full signature records, and anyone can recompute its hash chain from the method below — without our app, our servers, or an account. This page runs that method entirely in your browser.

Nothing is uploaded — verification happens locally, in this page.

The method

Every hash is a SHA-256 digest, lower-case hex, taken over the UTF-8 bytes of a canonical JSON serialisation. Canonical serialisation is deliberately simple so it is reproducible in any language:

Canonical JSON
  1. Object keys are emitted in ascending order by UTF-16 code unit
     (JavaScript's default string sort). Input key order is ignored.
  2. Minified: no whitespace after ':' or ','.
  3. Strings and finite numbers are escaped/formatted exactly as JSON does;
     negative zero (-0) normalises to "0".
  4. null is a real value; an absent key is different from null.
  5. undefined and non-finite numbers (NaN, Infinity) are not valid
     and never appear in a record.

1 — Each signature's entryHash

Take the signature record, remove its own entryHash field, canonicalise the rest, and SHA-256 it. The result must equal the stored entryHash.

entryHash = sha256_hex( canonical( record without "entryHash" ) )

2 — The chain links

Records are ordered. Each record's prevHash must equal the previous record's entryHash; the first record's prevHash is null. This is what makes reordering, insertion, deletion or edits detectable.

record[0].prevHash == null
record[i].prevHash == record[i-1].entryHash   (for i > 0)

3 — The document hash

A certificate also carries a certificateHash over its own body (a retention export carries an exportHash), computed the same way — remove that field, canonicalise, SHA-256 — so tampering with the document itself is caught too.

certificateHash = sha256_hex( canonical( certificate without "certificateHash" ) )
exportHash      = sha256_hex( canonical( export      without "exportHash" ) )

Independence

This method depends on nothing proprietary: SHA-256 and the canonical rules above. An auditor can implement it in a few lines in any language, or use the verifier on this page. A “verified” result means the records are internally consistent and unaltered as a chain; it does not, by itself, assert anything about the identity controls around signing, which are described in the app and its validation pack.

Questions about verification: support@gxpseal.com