Every equipment log in this system is cryptographically linked in a hash chain. You can independently verify that any record has not been tampered with using standard tools.
Paste an Entry Hash from a PDF and verify it step-by-step in your browser. No tools needed — uses your browser's built-in SHA-256.
You only need a SHA-256 hash function and a way to make HTTP requests. These are available on every operating system:
macOS / Linux
curl, echo, shasum (or sha256sum), python3, jq
All pre-installed. No downloads needed.
Windows
PowerShell (Invoke-WebRequest, Get-FileHash), or install Git Bash / WSL
Browser Only
Use the built-in verifier on this site, or any online SHA-256 tool (e.g. emn178.github.io/online-tools/sha256.html)
When a technician checks out equipment, the system creates a hash chain entry containing:
{
"sessionId": "...",
"equipmentId": "...",
"userId": "...",
"checkInAt": "2026-04-05T01:00:00.000Z",
"checkOutAt": "2026-04-05T02:30:00.000Z",
"checkInPhotoKey": "user/timestamp.jpg",
"checkOutPhotoKey": "user/timestamp.jpg",
"checkInPhotoHash": "a1b2c3d4...",
"checkInPhotoDuplicate": false,
"checkOutPhotoHash": "e5f6a7b8...",
"checkOutPhotoDuplicate": false,
"signatureHash": "9c0d1e2f...",
"durationMinutes": 90,
"calibrationSnapshot": { ... },
"integrityFlags": []
}
Three hashes are computed:
sequenceNumber:previousHash:dataHashReplace ENTRY_HASH with the Entry Hash from the PDF:
curl -s https://your-domain.com/api/verify/ENTRY_HASH | jq .
The response includes a chain object with payload, dataHash, previousHash, and entryHash.
Extract the payload, sort keys alphabetically, stringify without spaces, and hash:
# Using jq + shasum (macOS/Linux)
curl -s https://your-domain.com/api/verify/ENTRY_HASH \
| jq -cS '.chain.payload' \
| tr -d '\n' \
| shasum -a 256
# Or using Python
python3 -c "
import json, hashlib, sys
data = json.load(sys.stdin)
payload = data['chain']['payload']
canonical = json.dumps(payload, sort_keys=True, separators=(',',':'))
print(hashlib.sha256(canonical.encode()).hexdigest())
" < <(curl -s https://your-domain.com/api/verify/ENTRY_HASH)The output should match the Data Hashon the PDF. If it doesn't, the payload has been modified.
Combine the sequence number, previous hash, and data hash, then SHA-256:
# Format: sequenceNumber:previousHash:dataHash
echo -n "2:PREVIOUS_HASH_HERE:DATA_HASH_HERE" | shasum -a 256
# Or using Python
python3 -c "
import hashlib
seq = 2 # chain position from PDF
prev = 'PREVIOUS_HASH_HERE'
data = 'DATA_HASH_HERE'
input_str = f'{seq}:{prev}:{data}'
print(hashlib.sha256(input_str.encode()).hexdigest())
"The output should match the Entry Hash on the PDF.
The Previous Hash on this entry should be the Entry Hash of the preceding record (Chain Position N-1). Fetch the previous entry and confirm:
# Fetch previous entry using its hash curl -s https://your-domain.com/api/verify/PREVIOUS_HASH_HERE | jq .chain.entryHash
For the first entry (Chain Position #1), the Previous Hash is the literal string GENESIS.
To verify the entire chain, repeat steps 2-4 for every entry from #1 to the latest. If any hash doesn't match, the chain has been tampered with at that point.
# One-liner: full chain verification using the API
python3 -c "
import json, hashlib, urllib.request
BASE = 'https://your-domain.com'
# Start with the entry you want to verify
hash_to_check = 'ENTRY_HASH'
while hash_to_check and hash_to_check != 'GENESIS':
resp = urllib.request.urlopen(f'{BASE}/api/verify/{hash_to_check}')
data = json.loads(resp.read())
c = data['chain']
# Verify data hash
canonical = json.dumps(c['payload'], sort_keys=True, separators=(',',':'))
calc_data = hashlib.sha256(canonical.encode()).hexdigest()
assert calc_data == c['dataHash'], f'Data hash mismatch at #{c["sequenceNumber"]}'
# Verify entry hash
input_str = f'{c["sequenceNumber"]}:{c["previousHash"]}:{c["dataHash"]}'
calc_entry = hashlib.sha256(input_str.encode()).hexdigest()
assert calc_entry == c['entryHash'], f'Entry hash mismatch at #{c["sequenceNumber"]}'
print(f'#{c["sequenceNumber"]} OK {c["entryHash"][:16]}...')
hash_to_check = c['previousHash']
print('Chain verified successfully.')
"Each equipment photo is SHA-256 hashed at the time of submission. The hash is sealed into the chain payload. To verify a photo has not been altered:
# Hash the original photo file shasum -a 256 equipment-photo.jpg # Compare with the hash in the chain payload: # checkInPhotoHash = SHA-256 of the check-in photo # checkOutPhotoHash = SHA-256 of the check-out photo # The system also detects duplicate photos: # checkInPhotoDuplicate = true if photo was used before # checkOutPhotoDuplicate = true if photo was used before
If a photo has been reused from a previous session, the integrityFlags array in the chain payload will contain a warning with the original session ID and date.
The technician's hand-drawn signature is captured as a PNG data URL and SHA-256 hashed. This hash (signatureHash) is sealed into the chain, creating a unique biometric trace. If someone forges an entry under another technician's name, the signature hash will not match.
# The signatureHash in the payload is: # SHA-256 of the raw signature data URL # e.g., "data:image/png;base64,iVBOR..." # # To verify: echo -n "data:image/png;base64,iVBOR..." | shasum -a 256
Each completed session receives a signed timestamp from FreeTSA.org, an independent third-party Timestamp Authority. This proves the record existed at a specific time — even if the entire server were compromised, the TSA's signature is independently verifiable.
The TSA response (TSR) is stored in DER format (base64-encoded). You can verify it using OpenSSL:
# 1. Save the entry hash to a file echo -n "ENTRY_HASH_HERE" > /tmp/hash.txt # 2. Create a timestamp query from the hash openssl ts -query -data /tmp/hash.txt -sha256 -out /tmp/query.tsq # 3. Decode the stored TSR (base64 from the session) echo "TSR_BASE64_HERE" | base64 -d > /tmp/response.tsr # 4. Download FreeTSA certificates and verify curl -s https://freetsa.org/files/tsa.crt -o /tmp/tsa.crt curl -s https://freetsa.org/files/cacert.pem -o /tmp/ca.pem openssl ts -verify -data /tmp/hash.txt -in /tmp/response.tsr -CAfile /tmp/ca.pem -untrusted /tmp/tsa.crt # Expected output: "Verification: OK"
A successful verification confirms the record existed at the time shown in the TSA response, signed by an authority outside our control. The TSR is a cryptographic proof that cannot be backdated or forged without access to FreeTSA's private key.
If you don't have curl/jq, use PowerShell:
# Step 1: Fetch the entry
$resp = Invoke-RestMethod "https://your-domain.com/api/verify/ENTRY_HASH"
$payload = $resp.chain.payload | ConvertTo-Json -Compress -Depth 10
# Step 2: Compute data hash
$bytes = [System.Text.Encoding]::UTF8.GetBytes($payload)
$sha = [System.Security.Cryptography.SHA256]::Create()
$hash = $sha.ComputeHash($bytes)
$dataHash = -join ($hash | ForEach-Object { $_.ToString("x2") })
Write-Host "Data Hash: $dataHash"
# Step 3: Compute entry hash
$seq = $resp.chain.sequenceNumber
$prev = $resp.chain.previousHash
$input = "$seq`:$prev`:$dataHash"
$bytes2 = [System.Text.Encoding]::UTF8.GetBytes($input)
$hash2 = $sha.ComputeHash($bytes2)
$entryHash = -join ($hash2 | ForEach-Object { $_.ToString("x2") })
Write-Host "Entry Hash: $entryHash"Note: PowerShell's JSON key ordering may differ. For exact results, use the Python method above via WSL or Git Bash.
This page is publicly accessible. No authentication required.