Skip to content
Check without an account

Verify scan record

How the check works

A scan record from protsocials makes three statements: its content (JSON file and PDF) is unchanged, protsocials signed it, and an independent time-stamping authority confirmed that it existed at that time.

Upload the files you get when you download a scan record, or paste their content. The JSON file is enough for the hash. A complete check needs the manifest, the PDF, the signature and the timestamp together. Without the PDF it stays unchecked, and the result says so.

A scan record for one post is checked with its JSON file, its signature and its timestamp. It has no manifest, and its PDF is not signed.

The files are only read. Nothing is stored, and you need no account.

The signature is an advanced technical seal by protsocials, neither a qualified electronic signature nor a qualified electronic time stamp under the eIDAS Regulation.

The scan record's files

The file ending in “.zip”. It holds every file, so you don’t need the single ones.

Check single files

The file ending in “.json”, also that of a scan record for one post.

or choose a file

The file “….manifest.json”. Optional.

or choose a file

The file ending in “.pdf”. Optional; without it the PDF stays unchecked.

The file “….signature.json”. Optional.

or choose a file

The file “….tsr”. Optional.

The manifest's layout

The manifest consists of exactly these bytes: JSON in UTF-8, no whitespace and no trailing newline, with the keys in this order. The timestamp and the signature refer to these bytes.

{"manifest":1,"record":"<id>","json":"<sha256 of the JSON file>","pdf":"<sha256 of the PDF>"}

Public keys

The keys protsocials signs with are published at https://protsocials.com/.well-known/protsocials-record-keys.json, with the time each key began and stopped.

Check it yourself with openssl

Every check can also be run on your own computer, without trusting this page. You need the scan record’s files (R.json, R.pdf, R.manifest.json, R.signature.json and R.tsr) and sha256sum, openssl, curl and jq. Replace “R” with the name of your files.

A scan record for one post has no manifest: in steps 2 and 3, use R.json instead of R.manifest.json.

  1. 1. The content is unchanged

    The two values must be the “json” and “pdf” fields of the manifest.

    sha256sum R.json R.pdf
  2. 2. protsocials signed it

    The commands fetch the published key for the id in R.signature.json and check the signature over the manifest’s bytes. If it holds, you see “Signature Verified Successfully”.

    KEYS='https://protsocials.com/.well-known/protsocials-record-keys.json'
    KID=$(jq -r .kid R.signature.json)
    KID_PUB=$(curl -s "$KEYS" | jq -r --arg kid "$KID" '.keys[] | select(.kid == $kid) | .publicKey')
    printf '%s' "$KID_PUB" | tr '_-' '/+' | base64 -d > key.raw          # raw 32 bytes
    ( printf '\x30\x2a\x30\x05\x06\x03\x2b\x65\x70\x03\x21\x00'; cat key.raw ) \
      | openssl pkey -inform DER -pubin -out key.pem
    jq -r .signature R.signature.json | tr '_-' '/+' | base64 -d 2>/dev/null > sig.bin   # 64 bytes
    openssl pkeyutl -verify -pubin -inkey key.pem -rawin -in R.manifest.json -sigfile sig.bin
    # Signature Verified Successfully
  3. 3. An independent timestamp authority confirmed the time

    root.pem is the timestamp authority’s root certificate. Its operator publishes it; check its fingerprint against a second source. If the timestamp holds, you see “Verification: OK”.

    openssl ts -verify -in R.tsr -data R.manifest.json -CAfile root.pem
    # Verification: OK