Under the hood
How CaptureSeal works
Last updated
CaptureSeal fingerprints every photo and video with SHA-256, signs those fingerprints together with the time and place using a key locked in the phone’s secure hardware (Secure Enclave on iPhone, StrongBox/TEE on Android), and cross-checks the clock against internet time. Anyone can recompute the fingerprints and check the signature, so any later edit shows.
What happens when you press the shutter
- Capture. The camera saves the untouched original, exactly as the sensor produced it, with GPS in its metadata.
- Stamp. A stamped copy is made with the date, time, address, coordinates and a QR code burned into the pixels.
- Fingerprint. Both files get a SHA-256 fingerprint: a 64-character code calculated from every byte. Change anything and it changes completely.
- Cross-check the clock. Shortly before capture, the phone’s clock is compared with internet time, and the difference is recorded.
- Sign. The fingerprints, time, location and device go into a record (manifest.json) signed with an ECDSA P-256 key held in the phone’s secure hardware (Secure Enclave on iPhone, StrongBox/TEE on Android).
- Verify. Anyone recomputes the fingerprints and checks the signature with the public key inside the record, in the app, in a browser, or with OpenSSL.
What’s in the record?
Each capture has a manifest.json and a manifest.sig. The record holds the capture ID, kind (photo or video), the capture time and time zone, how the time was established (network-verified with the measured clock offset, or device clock), the GPS fix with its accuracy and the looked-up address, the device model and OS version, the camera and resolution, the filename, size and SHA-256 of the original and the stamped copy, and the public key and its key ID.
The signature is an ECDSA P-256 signature over SHA-256 of those exact bytes, DER-encoded. The key ID is the first 8 bytes of SHA-256 of the public key, in hex, which is what the verify page shows in groups of four.
How do I verify a capture?
A link alone doesn’t prove the photo; the check does. A verify link shows what the capturing phone recorded. Only the file you were sent can show that your copy matches it, so the page stays neutral until you drop that file in. It turns green only for an identical file, and red for anything else.
- Scan the QR code in the stamp with any phone camera. It opens the capture’s verify page, which shows the signed record (time, place, device key, capture ID) and re-checks its signature in your browser.
- Drop the file you were sent on that page, or a .seal Proof File on the verifier. It’s fingerprinted locally and compared with the record; nothing is uploaded. An identical file is genuine. A forwarded or screenshotted copy can’t match bit for bit: compare its visible stamp with the record, or ask for the original.
- Use OpenSSL if you’d rather trust nothing of ours. Try it on the demo capture: download its manifest.json, manifest.sig and original.jpg.
Verify with OpenSSL
# 0. A Proof File is a standard zip inside: unpack it (or use the separate demo files)
unzip "CaptureSeal F1E33C32.seal" -d proof && cd proof
# 1. Rebuild the public key from the record (or use key.pem from the package)
KEY=$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["signing"]["publicKey"])' manifest.json)
{ printf '3059301306072a8648ce3d020106082a8648ce3d030107034200' | xxd -r -p; printf '%s' "$KEY" | base64 -d; } \
| openssl pkey -pubin -inform DER -out key.pem
# 2. Check the signature over the exact bytes of manifest.json
openssl dgst -sha256 -verify key.pem -signature manifest.sig manifest.json
# → Verified OK
# 3. Check the key ID shown on the stamp's verify page
printf '%s' "$KEY" | base64 -d | openssl dgst -sha256 -r | cut -c1-16 | tr a-f A-F
# 4. Compare the media's fingerprint with "sha256" in manifest.json
# (the stamped copy is under "sealed", the untouched original under "original")
shasum -a 256 *.jpg
Tested on macOS with LibreSSL/OpenSSL 3. On Linux, sha256sum works in place of shasum -a 256.
Sharing is always free: send the photo or a .seal proof file and anyone can verify it in CaptureSeal or at captureseal.link/verify. We only charge for hosting verify links.
What’s in a Proof File (.seal)?
A Proof File is one file anyone can verify. It opens in CaptureSeal on iPhone, with a preview right in Files, Mail and Messages; on any computer, drop it on captureseal.link/verify. Inside, it’s a standard, uncompressed zip archive, so it stays future-proof and inspectable with ordinary tools:
captureseal: the first entry, a marker naming the format (application/vnd.captureseal.proof;version=1), the same trick EPUB books use;CaptureSeal-<code>.jpg(or.mov): the stamped photo or video, exactly as sealed;manifest.jsonandmanifest.sig: the signed record and its signature;README.txt: how to check it.
Rename it to .zip and any unzip tool opens it; the verifier accepts both. Try the demo Proof File.
How a verify link is tied to your device
A capture’s ID is printed in its QR code, so anyone who sees the photo can read it, and anyone can sign a record with a key of their own. To stop a stranger from publishing a fake record under your capture’s ID, the QR code also names your device’s key: it links to /v/<capture ID>#<original fingerprint>.<key ID>.
- The verify page shows only the record signed by the key named in the link. A record from any other key is never shown in its place.
- If the named key hasn’t published a record, the page says the capture “hasn’t been published by the capturing device”. You can still check a file against the fingerprint in the link.
- If someone opens a bare link without a key and more than one device has published under that ID, the page lists every record with its key ID and asks you to trust only the one that matches the sender’s.
- The part after
#never leaves your browser, so the server doesn’t learn which photo you scanned.
Why a copy sent over WhatsApp won’t match
Messaging and social apps recompress photos and videos to save data. The picture looks the same, but the bytes differ, so the fingerprint differs. That’s the seal working as intended: it can’t tell a harmless recompression from an edit. The QR code still leads to the record, so the recipient can see the original time and place and ask for the original file.
What it proves, and what it can’t
A passed check shows the file wasn’t edited after capture, the stamped time and place are the recorded ones, and the record came from the device whose key ID it shows. It can’t show the scene was real, who held the phone, or GPS truth on a modified device. The security page covers each limit.
Questions
Frequently asked questions
Why both a stamp and a signature?
The stamp is for people: it shows the time and place at a glance. But anyone can type a stamp with an editor. The signature is for checking: it ties the fingerprints, time and place to one device key, so an edit shows up.
What is a SHA-256 fingerprint?
A 64-character code calculated from every byte of a file. Two different files practically never share one, and changing a single pixel, or re-saving the file, gives a completely different code.
Where is the signing key?
In the phone’s secure hardware: the Secure Enclave on iPhone, or StrongBox or the Trusted Execution Environment (TEE) on Android. It can use the key but never reveals it. Not even CaptureSeal can read or copy it. Only the public key leaves the phone, inside each record.
How accurate is the time?
When the phone is online, CaptureSeal compares its clock with internet time shortly before capture and records the offset. Offline, the record says “Device clock”, so a reader knows the time wasn’t cross-checked.
What does a verify link publish?
Only the signed record: time, location and address, device model and OS, fingerprints and the public key. Never the photo or video. You can withdraw a link at any time.
Can someone publish a fake record under my photo’s ID?
They can publish a record signed with their own key, but your QR code and verify links name your device’s key, so the verify page shows only your record. Their record would be listed separately, with its different key ID, and only to someone opening a bare link without a key.
Coming soon to iPhone & Android
Be first to seal your photos
CaptureSeal is coming soon to iPhone and Android. Leave your email and we’ll tell you the day it launches.