Skip to main content

archiviomd-verify

Standalone verification tool for ArchivioMD and ArchivioID — two WordPress plugins for cryptographic document signing.

Zero WordPress dependency. Given any published post URL the tool fetches the plugin's public REST endpoint and verifies every cryptographic layer locally, printing a pass/fail result for each one.


Requirements

  • Python 3.8 or later
  • Internet access to the site being verified (and to Rekor / Cloudflare DoH for transparency log and DANE checks)

Check your Python version:

python3 --version

Installation

1. Clone or unzip

Place archiviomd-verify.py, archiviomd-verify.html, and requirements.txt in any directory.

2. Install Python dependencies

pip install -r requirements.txt

This installs cryptography, which enables offline Ed25519, ECDSA P-256, and RSA verification. Everything else is Python stdlib.

For SLH-DSA (post-quantum, NIST FIPS 205) offline verification, also install:

pip install pyspx
Binary Purpose Install
openssl CMS/PKCS#7 and RFC 3161 timestamp offline verify apt install openssl / brew install openssl
gpg OpenPGP (ArchivioID) offline verify apt install gnupg / brew install gnupg / Gpg4win on Windows

Run python3 archiviomd-verify.py --verbose https://example.com/post to see which binaries are detected.


Usage

Verify a post

python3 archiviomd-verify.py https://example.com/my-signed-post

Verify with an explicit Ed25519 public key

python3 archiviomd-verify.py https://example.com/post --pubkey <64-hex-chars>

Use this when the public key is not auto-discoverable from the site's .well-known/ endpoint.

Inspect a Rekor transparency log entry

python3 archiviomd-verify.py --rekor 12345678

Verify an RFC 3161 timestamp file

python3 archiviomd-verify.py --tsr response.tsr --tsq request.tsq

Provide --tsa-cert-url if the TSA certificate is not bundled in your system CA store.

Check DANE DNS records for a domain

python3 archiviomd-verify.py --dane example.com

List all ArchivioID PGP keys registered on a site

python3 archiviomd-verify.py --pgp-keys https://example.com

Inspect ArchivioID PGP signatures for a specific post

python3 archiviomd-verify.py --pgp-keys https://example.com --pgp-post 42

Verbose mode — show dependency status first

python3 archiviomd-verify.py --verbose https://example.com/post

Skip TLS certificate verification (staging / self-signed certs)

python3 archiviomd-verify.py --no-verify-ssl https://staging.example.com/post

Warning: Only use --no-verify-ssl on networks you control. It disables all TLS certificate validation.


What gets checked

# Layer Offline? Requires
1 Content hash (SHA-256/512/etc) ✓ (non-HMAC) stdlib
2 Ed25519 bare + DSSE envelope ✓ cryptography
3 SLH-DSA (NIST FIPS 205) ✓ pyspx
4 ECDSA P-256 DSSE ✓ cryptography
5 RSA PSS / PKCS#1v15 ✓ cryptography
6 CMS / PKCS#7 detached sig ✓ openssl binary
7 JSON-LD / W3C Data Integrity server-side —
8 Rekor transparency log ✓ (inclusion proof) internet
9 RFC 3161 trusted timestamp ✓ openssl binary
10 DANE DNS TXT + TLSA ✓ internet (DoH)
11 OpenPGP (ArchivioID bolt-on) ✓ (if gpg present) gpg binary

Output and exit codes

Each section prints one of:

  • ✓ — check passed
  • ✗ — check failed
  • ⚠ — warning or missing optional dependency
  • · — informational

Exit code 0 = all performed checks passed.
Exit code 1 = one or more checks failed.

This makes the tool safe to use in CI/CD pipelines:

# GitHub Actions example
- name: Verify post integrity
  run: python3 archiviomd-verify.py https://example.com/post
# Shell script example
python3 archiviomd-verify.py https://example.com/post || exit 1

Browser verifier

Open archiviomd-verify.html in any modern browser. It performs client-side verification using the Web Crypto API and requires no installation. Supports layers 1–10 (Ed25519 DSSE, ECDSA P-256 DSSE, content hash, Rekor, RFC 3161 instructions, DANE, JSON-LD).

Layers that require native binaries (SLH-DSA offline, RSA offline, CMS/PKCS#7, OpenPGP) are noted in the UI with a prompt to use the Python CLI.


Notes on HMAC mode

If the site uses HMAC content hashing, offline verification of the content hash requires the ARCHIVIOMD_HMAC_KEY secret, which is never published. The tool will report the server-verified status only.


Verification file format

ArchivioMD attaches a downloadable verification file (JSON) to each signed post — typically accessible via a badge or download link on the post. The CLI references this file in several places. Its structure is:

{
  "post_id": 42,
  "verification_data": {
    "content_hash": {
      "algorithm": "sha256",
      "hash": "abcdef..."
    },
    "ed25519": {
      "signature_hex": "...",
      "public_key_url": "https://example.com/.well-known/ed25519-pubkey.txt"
    },
    "rsa": {
      "signature_hex": "...",
      "scheme": "rsa-pss-sha256"
    },
    "cms": {
      "signature_b64": "..."
    },
    "rfc3161": {
      "tsr_url": "https://example.com/wp-content/uploads/archiviomd/42.tsr",
      "tsq_url": "https://example.com/wp-content/uploads/archiviomd/42.tsq"
    }
  }
}

When verifying manually with openssl:

# CMS / PKCS#7
echo "<signature_b64 value>" | base64 -d > sig.der
openssl cms -verify -inform DER -in sig.der -content message.bin -noverify

# RSA (PSS)
echo "<signature_hex value>" | xxd -r -p > sig.der
openssl dgst -sha256 -verify rsa-pubkey.pem -signature sig.der message.bin

# RFC 3161
openssl ts -verify -in 42.tsr -queryfile 42.tsq -CAfile /etc/ssl/certs/ca-certificates.crt

Reproducible installs and version pinning

requirements.txt pins cryptography to a tested range (>=41.0.0,<47). For CI environments or any situation requiring exact reproducibility, use the lock file instead:

pip install -r requirements-lock.txt

To regenerate the lock file after updating requirements.txt:

pip install -r requirements.txt
pip freeze > requirements-lock.txt

For hash-verified installs (maximum supply-chain security), use pip-tools:

pip install pip-tools
pip-compile --generate-hashes requirements.txt -o requirements-lock.txt
pip install --require-hashes -r requirements-lock.txt

RFC 3161 timestamp — what it proves and what it doesn't

When the tool reports a timestamp as VALID, it means:

  • A trusted third-party TSA (timestamp authority) cryptographically signed a hash of the content at the recorded time
  • The content hash existed before that timestamp
  • The TSA's signature has not been tampered with

It does not mean:

  • The content itself is authentic or unmodified since then
  • The author is who they claim to be
  • The content hasn't been replaced (the hash in the TSR must be cross-checked against the content hash above it in the output)

For compliance or legal use, the RFC 3161 timestamp is evidence of prior existence at a specific time, not a guarantee of content integrity on its own. Treat it as one layer in a chain — the content hash, the signature, and the timestamp together form the complete proof.


Browser verifier — CORS dependency

The HTML verifier (archiviomd-verify.html) makes cross-origin fetch requests to the site being verified. This works when:

  • The WordPress site sends permissive Access-Control-Allow-Origin CORS headers on its REST endpoints (ArchivioMD enables this by default)
  • The HTML file is opened locally (file://) or served from an allowed origin

It will fail silently or show a CORS error when:

  • A WAF (Cloudflare, Sucuri, Wordfence, etc.) strips CORS headers
  • A WordPress security plugin blocks REST API access to unauthenticated requests
  • The site is behind HTTP Basic Auth or an IP allowlist

If you see a CORS error, use the Python CLI instead — it runs as a normal HTTP client and is not subject to browser CORS restrictions:

python3 archiviomd-verify.py https://example.com/post

Platform notes

Windows: ANSI color output requires Windows 10 version 1903 or later with a modern terminal (Windows Terminal, VS Code terminal). On older systems output renders in plain text without color.

macOS: openssl installed via Homebrew may shadow the system LibreSSL. Either works for the tool's purposes.

Linux: All features work with standard package manager installs.

Metadata

Release files for archiviomd-verify 1.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for archiviomd-verify 1.0.4
File Size Uploaded Provenance
archiviomd_verify-1.0.4.tar.gz 23.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for archiviomd-verify 1.0.4
File Interpreter ABI Platform
archiviomd_verify-1.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 43.5 kB

Release files / archiviomd_verify-1.0.4.tar.gz

Download URL archiviomd_verify-1.0.4.tar.gz
Size 23.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b1566f55d98f84538e04e2b5327f1628cdf4c05b0ab953b11349a4eedea65dbb
BLAKE2b-256 checksum
How to use checksums
d0e0c39d4b360a509e643d606be5efb9a8c53b85ddab36c58495505f2198f048
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 12, 2026.

Transparency log

Release files / archiviomd_verify-1.0.4-py3-none-any.whl

Download URL archiviomd_verify-1.0.4-py3-none-any.whl
Size 20.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dd30c34a08cda3c71f92efa12c66731cbb1af4ec2ad44dea17389e46c1870c88
BLAKE2b-256 checksum
How to use checksums
268ac2b4faaa721eea385ac98cdbbad963dd3d10b14a471292692f6c6ef208bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 12, 2026.

Transparency log

Security for archiviomd-verify 1.0.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for archiviomd_verify-1.0.4.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.4 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page