For anyone who receives a photo or video taken with TUVAMBES GeoCam : GPS Camera (package com.tuvambes.geocam) — courts, lawyers, insurers, investigators, their experts, and anyone else.
Every photo and video GeoCam saves carries a digital signature made inside the phone's secure hardware. Check whether a file is an unchanged GeoCam original — in the GeoCam app if you have it, or right here if you don't. This page also explains exactly how the check works, and what a result does and does not show.
| Who | How to check | Where your file goes |
|---|---|---|
| You have the GeoCam app | In the app: Settings › Security & authenticity › Verify media authenticity, or open the file with GeoCam (section 6). | It stays on your phone. Nothing is uploaded. |
| You don't have the app | Upload it in the online checker below (section 1). | Sent over an encrypted connection to TUVAMBES's server, checked, and deleted immediately after the check (section 2). |
| Experts, offline | The reference verifier, geocam_verify.py (section 7). | It stays on your computer. |
1.Check a file online
For anyone without the GeoCam app. Choose the photo, video or evidence package exactly as you received it — sent as a file or document, not re-sent as a photo through a chat app.
JPEG photo, MP4 video, or a GeoCam evidence package (.zip) — up to 100 MB; 20 checks every 10 minutes.
2.How the online check works
What happens to your file, step by step:
- You choose a file and confirm the notice. The checker accepts JPEG photos, MP4 videos and GeoCam evidence packages (.zip), up to the size shown above. Nothing is sent until you press Check file.
- Your browser uploads it over an encrypted (HTTPS) connection to TUVAMBES's web server at tuvambes.in, which is hosted by Hostinger. There is no account, no sign-in and no cookie.
- The server checks it with the method in section 9 — the same checks the GeoCam app makes. It also uses Google's public list of revoked phone certificates, which the server downloads at most once a day; nothing about you or your file is sent to Google. An evidence package is unpacked into temporary files to be checked.
- The file is deleted as soon as the check finishes — before the result is sent back to you — together with anything unpacked from it. If something goes wrong, it is deleted all the same, and the server software also removes every upload when the request ends.
- Only the result comes back to your browser. TUVAMBES does not keep the file, a copy, the result or any record of what the file showed. No person looks at it, it is not analysed for faces, and it is not used for anything else.
- Keep the result yourself if you need it: print it or save it as a PDF from your browser. We can't send it to you later, because we don't keep it.
- What is kept: our hosting provider's standard server logs — your IP address, the time, the page address and your browser type, never the file — kept for a limited time for security; and, to stop abuse, a counter linked to a one-way coded form of your IP address, deleted within an hour.
Files larger than the limit, or many files at once: use the GeoCam app or the reference verifier (section 7), which check files without uploading them. For evidence, a check that anyone can repeat — in the app or with the reference verifier — carries more weight than a printout of this page.
3.Is this checker genuine?
- Use it only at https://tuvambes.in/geocam/verification. GeoCam's reports and evidence packages link to this address.
- The checker uses the same trust list as the app, signed by TUVAMBES, and refuses to give any result if that list has been changed.
- Each release of the checker's files is listed, with their SHA-256 fingerprints, in
verifier-manifest.json, signed with the TUVAMBES root key (verifier-manifest.sig, checkable with the public key intuvambes_root.pem). The checker refuses to give results if its own files don't match. To check the list yourself:openssl x509 -in tuvambes_root.pem -pubkey -noout > tuvambes_root_pub.pem openssl dgst -sha256 -verify tuvambes_root_pub.pem -signature verifier-manifest.sig verifier-manifest.json sha256sum geocam_verify.py # compare with verifier-manifest.json - You don't have to trust this website alone: the same file gives the same result in the GeoCam app and with the offline reference verifier.
4.The four results
| Result | What it means |
|---|---|
| Verified | The file was signed by the official GeoCam app on a genuine phone and has not changed since GeoCam saved it. If the only difference is that the phone hid the location in the file's standard details — Android does this when another app opens or receives a file — the result is still Verified, with a note; the signed location stays in the record. |
| Verified – Mark-up Verified – Measurements Verified – Mark-up & measurements | As Verified, but mark-up (drawings, shapes or text), measurements or both were added in GeoCam before saving, and the signed record lists them. They are not part of the scene, and measurements are estimates. When the original was kept, the photo as captured is a separate signed file, linked by its provenance ID. |
| Modified | The file carries a genuine GeoCam signature, but its picture or video, its signed record, or the location written in its details was changed after it was signed. It shows that a change was made — not who made it or why. |
| Unverified | Where the file came from can't be confirmed: it has no signature (apps that re-save or compress files — most chat and social apps — remove it), it was not signed by the official app on a genuine phone, the signing key was withdrawn, the signing phone reported its security as off, or the file is damaged or in a format or version that can't be checked. Unverified is not a finding that the file was edited. |
5.What GeoCam signs
When GeoCam saves a capture, it writes a signed record into the file and signs it, together with a fingerprint (SHA-256) of the picture or video, using a key that was created inside the phone's secure hardware and never leaves it. The record holds:
| Part | Contents |
|---|---|
| Time | Capture time (UTC) and time-zone offset from the phone's clock. When the phone had them, its satellite (GNSS) time and network time at the same instant, and whether automatic date & time was on. The time of signing. |
| Place | Latitude and longitude (WGS 84), accuracy, altitude and the GPS fix time; the satellites used and in view and their systems (for example GPS, Galileo, NavIC); whether the phone reported a mock-location (fake GPS) app. |
| Phone & app | The phone's maker, model and Android version; the app's package, version and build. |
| Capture | Photo or video; random capture and provenance IDs; for an edited copy, the provenance ID of its kept original; a list of what GeoCam did (markup, measure, dual-lens, orientation-pair, camera-original); any measurements, with their ± estimates, method and points. |
| Signer | The public key, and the phone's Android key-attestation certificate chain, which shows that the key was created in secure hardware for the app com.tuvambes.geocam, and reports the phone's security state — verified boot, bootloader lock, Android version and security patch level. |
The GeoStamp printed on the photo is part of the picture; the signed record is the authoritative copy of what GeoCam recorded. Satellite time, satellites and the phone model can be switched off in the app (Settings › Security & authenticity › Record satellite time & GPS signal); the result then says the time is from the phone's clock only.
6.Check a file in the app
On every plan, offline, with nothing uploaded:
- Settings › Security & authenticity › Verify media authenticity, then choose the photo or video; or
- open the file with GeoCam from another app (Open with or Share); or
- tap the shield on a capture in GeoCam's own gallery.
The result shows the details of the signed record and the signer. Export report (PDF) saves a verification report; Export evidence package saves the files themselves together with the report and the custody log (section 8).
7.Check a file offline (experts)
Anyone without the app can use the online checker (section 1). To check files without uploading them — or to repeat a check independently, as an expert — use our reference verifier, geocam_verify.py — a single, readable Python script that follows the method in section 9 and gives the same result as the app and the online checker (we test all three on the same set of files). It runs on Windows, macOS and Linux, with Python 3.9 or later:
pip install cryptography
python geocam_verify.py IMG_20261005_101530.jpg
python geocam_verify.py --package GeoCam_evidence_20261005_103000.zip
python geocam_verify.py --json VID_20261005_102000.mp4
It prints each file's SHA-256, the result and its explanation, the signed record and the signer checks. --json gives the same as machine-readable JSON. Exit code 0 means every file is Verified, 1 that a file is Modified, 2 that a file is Unverified or a package or custody check failed. Everything runs on your computer; the optional --google-revocation also downloads Google's public attestation status list, and a revoked certificate in the signer's chain then makes the file Unverified, as on the online checker.
8.Evidence packages & custody logs
An evidence package is a ZIP file made by the app on request. Its files are stored as they are, not recompressed:
- the capture's files exactly as GeoCam stored them — the capture, its kept original (when it was edited) and the camera's own photo (when kept);
verification_report.pdfandverification_report.json— the check of each file, with its SHA-256;custody_log.json— the capture's signed custody log;README.txtandSHA256SUMS.txt— the SHA-256 of every file in the package.
To check that a package is complete and unchanged:
sha256sum -c SHA256SUMS.txt # Linux
shasum -a 256 -c SHA256SUMS.txt # macOS
certutil -hashfile <file> SHA256 # Windows, file by file
The custody log records, for one capture, each time it was captured and signed, saved to the phone gallery, shared, put in a PDF report, exported in a verification report or evidence package, uploaded to or downloaded back from the user's own Google Drive (Pro), or checked — with the time (phone clock, UTC) and the file's name, size and SHA-256 at that moment. Each entry includes the fingerprint of the one before and is signed with the same hardware key that signed the capture, so an entry can't be changed, removed, reordered or moved to another capture without the check failing. It records only what happened inside GeoCam on that phone — not what happened to copies after they left the app. It can be switched off in Settings.
9.The method, step by step
For experts. Byte offsets are zero-based; a range [start, end) includes start and excludes end.
9.1 Where the signature is
- JPEG: an APP11 segment (marker
FF EB) whose data begins with the 14 bytesTUVAMBES-AUTH\0, followed by the manifest (UTF-8 JSON). It is placed after the EXIF / JFIF segments. - MP4: a top-level
uuidbox whose 16-byte user type is the ASCIITUVAMBESAUTH0001, followed by the manifest. It is appended at the end of the file.
The media is the file with that segment or box removed.
9.2 The manifest
{ "schemaVersion": 2,
"signedPayloadB64": "<base64 of the signed payload bytes>",
"signAlg": "ES256",
"signatureB64": "<base64 of an ECDSA P-256 / SHA-256 signature, ASN.1 DER>",
"certChainB64": ["<leaf certificate, DER, base64>", "...", "<root>"] }
The signature covers exactly the payload bytes as embedded — nothing is re-serialised before checking. The payload is UTF-8 JSON with these fields:
| Field | Meaning |
|---|---|
schemaVersion | 2 |
assertion | The signed record (section 5), e.g. capturedAtUtc, tzOffsetMinutes, timeSource (gnss, network or device), gnssTimeUtc, networkTimeUtc, autoTime, signedAtUtc, latitude, longitude, gpsAccuracy, altitude, fixTimeUtc, satellitesUsed, satellitesInView, constellations, mockLocationDetected, deviceMake, deviceModel, osRelease, appId, appVersion, buildId, captureId, provenanceId, parentProvenanceId, transform, measurement. |
mediaHashAlg | SHA-256 |
mediaHashHex | SHA-256 of the media with every byte of zeroedRanges read as 0x00 (9.3). |
zeroedRanges | The location-metadata byte ranges of the media, sorted and non-overlapping: [{"start", "end", "sha256"}], each with the SHA-256 of its bytes at signing. |
signAlg | ES256 (ECDSA P-256 with SHA-256). |
publicKeyB64 | The signing key's SubjectPublicKeyInfo (DER), base64. |
9.3 Why location bytes are zeroed
On Android 10 and later, when an app without the media-location permission opens or receives a photo or video, Android overwrites its location metadata with zeros, in place — the file keeps its size but its fingerprint changes. GeoCam therefore signs the media with those bytes read as zero, and signs each range's own fingerprint separately. The ranges are: in a JPEG, the value bytes of every tag in the EXIF GPS IFD; in an MP4, the ©xyz, loci, gps and gps0 boxes, from their type field to their end. On checking, each range is unchanged (its fingerprint matches), hidden (all zeros) or changed (anything else). The picture and everything else must match exactly.
9.4 The checks, in order
The result is the first rule that applies:
- Not a JPEG or MP4 → Unverified (AUTH-009).
schemaVersionhigher than 2 → Unverified (AUTH-015).- No signature segment or box → Unverified (AUTH-001).
- The manifest or payload can't be read → Unverified (AUTH-010).
- The signer. Each certificate in the chain must be signed by the next (ECDSA or RSA, with SHA-256 or SHA-384) up to one of Google's hardware attestation roots (9.5); the leaf's public key must be
publicKeyB64; every certificate must be valid atcapturedAtUtc; and the leaf's key-attestation extension (OID1.3.6.1.4.1.11129.2.1.17) must show a key kept in secure hardware (TEE or StrongBox) for the appcom.tuvambes.geocam. Otherwise → Unverified (AUTH-006; AUTH-014 when there is no chain). - The key or the leaf certificate is on TUVAMBES's withdrawn list → Unverified (AUTH-007).
- The online checker, and the reference verifier with
--google-revocation: a certificate in the chain is on Google's attestation status list (revoked or suspended, for example because a phone's keys leaked) → Unverified (AUTH-007). The app works offline and uses the withdrawn list in its signed trust list. - The attestation's root of trust reports a verified-boot state other than Verified, or an unlocked bootloader → Unverified (AUTH-018).
- The signature over the payload bytes does not verify with
publicKeyB64→ Modified (AUTH-003). - The media hash (9.3) differs from
mediaHashHex→ Modified (AUTH-004). - A location range is changed → Modified (AUTH-016).
- Otherwise → Verified, or Verified – Mark-up / Measurements when
transformlistsmarkupormeasure; with a note when a location range is hidden.
Notes also report a mock-location flag, and how far the phone's clock was from satellite (else network) time at capture; a difference over 60 seconds is flagged. A report also shows each certificate's SHA-256 and the SHA-256 of the app signing certificate bound to the key — TUVAMBES will confirm on request whether a fingerprint belongs to the official app.
9.5 Trust anchors
| Root | Public key (SPKI) SHA-256 |
|---|---|
| Google Hardware Attestation Root (RSA-4096) | feb2ea7551ee316ed4bb443c8293b884dbfdea40b603ee3e4f4a897e4580fbae |
| Google Key Attestation CA1 (ECDSA P-384) | 3ee44512a1af2beb39c889490c60ea3f82e43f5d5a5532f5ab9419f676cd07ec |
Google publishes these roots at developer.android.com. The app carries them, and the withdrawn-key list, in a trust list signed by TUVAMBES; the reference verifier includes the same roots.
9.6 The custody log
Each entry's hashHex is the SHA-256 of the canonical JSON of {recordId, seq, type, atUtc, fileSha256, fileSize, fileName, detail, prevHashHex} — keys sorted, no spaces, UTF-8. prevHashHex is the previous entry's hashHex (empty for the first), seq counts from 0, and signatureB64 is an ECDSA P-256 / SHA-256 signature of the same bytes by publicKeyB64 — the key that signed the capture.
9.7 Earlier format
Pre-release builds of GeoCam wrote manifest version 1, with a plain media hash; every release build writes version 2. The app still checks version 1 files; the reference verifier reports them as Unverified (AUTH-002) and asks you to check them in the app.
10.Diagnostic codes
| Code | Meaning | Result |
|---|---|---|
| AUTH-001 | No GeoCam signature in the file | Unverified |
| AUTH-002 | Earlier signature format (reference verifier only) | Unverified |
| AUTH-003 | The signed record no longer matches its signature | Modified |
| AUTH-004 | The picture or video no longer matches its signature | Modified |
| AUTH-006 | Not signed by the official app on a genuine phone | Unverified |
| AUTH-007 | The signing key or a certificate was withdrawn by TUVAMBES or revoked by Google | Unverified |
| AUTH-008 | The file is damaged | Unverified |
| AUTH-009 | Not a JPEG photo or MP4 video | Unverified |
| AUTH-010 | The signature block can't be read | Unverified |
| AUTH-014 | No certificate chain to check the signer | Unverified |
| AUTH-015 | Signed by a newer version of GeoCam | Unverified |
| AUTH-016 | The location in the file's details was changed after signing | Modified |
| AUTH-017 | An earlier-format capture whose location the phone hid (app only) | Unverified |
| AUTH-018 | The signing phone reported its security as off | Unverified |
Codes AUTH-005 and AUTH-011 to AUTH-013 are reserved.
11.What a result does not show
- A result shows whether a file matches the signature GeoCam made when it saved it, and what the signed record states. It does not show that the scene was not staged, or that what is depicted is true — a photo of a screen or of a printed picture can be signed too.
- The capture time comes from the phone's clock. Satellite or network time, when shown, is an independent reference the phone held at capture; “confirmed by satellite time” means the phone's clock agreed with it to within 60 seconds.
- The location comes from the phone's location services, with the accuracy the phone reported. A mock-location flag is recorded when the phone reports one, but not every way of faking a location can be detected.
- The GeoStamp, and any mark-up or measurements, were added by the app. Measurements are estimates with the stated uncertainty and should be confirmed with calibrated instruments where exact values matter.
- The signature identifies the phone (the app installation) that signed the file — not the person who pressed the shutter.
- The check relies on the phone's secure hardware and Google's attestation. Phones that report an unlocked bootloader or unverified software are not trusted.
12.Using GeoCam files as evidence
A verification result supports the authenticity of the file — that it is the file GeoCam saved, unchanged. What the file shows is usually confirmed by a witness, often the person who took it. To give a capture the most weight:
- Keep the files exactly as GeoCam saved them, and keep the original beside any edited copy (on by default).
- Export an evidence package soon after the event, and record its SHA-256 independently (section 8).
- Hand over the evidence package — the files and the report — rather than screenshots or forwarded copies.
- Keep a note of who handled the files and when, after they left the app.
- Be ready for the person who took the photo or video to confirm it, and, where the law requires, for a certificate or an expert.
Some examples of the rules that may apply:
- India. Under Section 63 of the Bharatiya Sakshya Adhiniyam, 2023, an electronic record is submitted with a certificate in the form set out in its Schedule — Part A by the party and Part B by an expert — which includes the record's hash value. A verification report gives the SHA-256 of each file.
- United States. Federal Rule of Evidence 901(b)(9) allows authentication by evidence about a process or system that produces an accurate result; Rules 902(13) and 902(14) allow self-authentication by the certification of a qualified person, including for data copied from a device and identified by its hash. The published method and the reference verifier support such evidence and certifications.
- European Union. Under the eIDAS Regulation (EU) No 910/2014, an electronic signature, seal or time stamp cannot be denied legal effect or admissibility as evidence solely because it is electronic or not qualified (Articles 25(1), 35(1) and 41(1)). GeoCam's signatures and time records are not qualified electronic signatures, seals or time stamps.
- China. The Supreme People's Court's Provisions on Several Issues Concerning the Trial of Cases by Internet Courts (2018), Article 11, recognise electronic signatures, trusted time stamps and hash-value verification among the technical means of showing that electronic data has not been tampered with.
- Elsewhere. Many electronic-evidence laws follow the UNCITRAL Model Law on Electronic Commerce (1996), whose Article 9 weighs how reliably a record was generated, stored and kept intact — what the signature, the custody log and the published method describe.
13.Contact
Questions about this method, or a request to confirm the official app's signing-certificate fingerprint: contact@tuvambes.in. A file uploaded to the online checker is deleted as soon as it has been checked (section 2); otherwise files never reach TUVAMBES unless you send them to us. See also the Terms and the Privacy Policy.
↑ Back to top