Sign / verify an entire [Website]/[Gemini capsule]/[Gopher hole]
Go to file
nervuri b1726ab766 README: clarify signing explanation 2021-03-22 13:40:34 +02:00
LICENSE Initial commit 2021-03-19 19:04:11 +00:00 README: clarify signing explanation 2021-03-22 13:40:34 +02:00
netsigil include .hidden files 2021-03-21 18:40:05 +02:00


NetSigil signs directories and verifies directory signatures. It allows anyone to check if files on a server have been tampered with (by the hosting provider, attackers, etc). Use it to:

  • Sign an entire [Website]/[Gemini capsule]/[Gopher hole]
  • Verify any file on a signed [Website]/[Gemini capsule]/[Gopher hole] - not yet implemented


netsigil --sign <dir>    # Sign a local copy of your site
netsigil --verify <URL>  # Verify remote signature

Uses signify. GPG support might be added later.

How it works


  1. Walks you through installing signify, if not already installed (apt only, for now).
  2. Walks you through generating a keypair; stores keys in $XDG_DATA_HOME/signify/ (or ~/.local/share/signify/).
  3. Generates a SHA256SUMS file containing hashes of all files in the specified directory (including subdirectories).
  4. Puts and SHA256SUMS into a tar.gz archive.
  5. Signs the archive, embedding the signature in the gzip header.
  6. Saves the signed archive within the directory, as .well-known/signature-bundle.

Best used within a script that synchronizes local files with the server. This is how I use it.


Verification is not yet implemented, but here is an approximation of how it will work:

  1. User runs netsigil --verify scheme://
  2. Download scheme://
  3. If we already have a SHA256SUMS file for scheme://, then go to 7.
  4. Download scheme://
  5. If not already present, extract from signature-bundle and store it locally (Trust on first use).
  6. Use to verify signature-bundle.
  7. Extract SHA256SUMS from signature-bundle and store it locally.
  8. Check if the hash of file matches the one in SHA256SUMS. If it does, stop here. Perhaps output the requested file to stdout.
  9. On hash mismatch: if step 2 was true, then go to step 3; else, stop.

Note that in this example, .well-known is under ~user, not directly under This is to account for multi-user systems (pubnixes/tilde communities).

Verification can also be done manually. Here is an example for the Gemini protocol (using agunua to download files):

# Download `signature-bundle`
agunua --insecure --binary gemini:// > signature-bundle
# Extract the public key
tar -xf signature-bundle
# Verify `signature-bundle`
signify -Vz -p -x signature-bundle >/dev/null && echo 'Signature OK'
# Extract `SHA256SUMS`
tar -xf signature-bundle SHA256SUMS
# Download two files from the capsule, mirroring the directory structure
agunua --insecure --binary gemini:// > contact.gmi
mkdir keys && agunua --insecure --binary gemini:// > keys/index.gmi
# Verify them both
sha256sum -c --ignore-missing SHA256SUMS


If you don't want to make an account here, just shoot me an email:

The idea for this program spawned on the Gemini mailing list. Special thanks to Christophe Henry and Francesco Camuffo.