Forensic Methodology Whitepaper
Technical reference for prosecutors, defense counsel, expert witnesses, and agency Information Security Officers evaluating DVR Time Traveler's reports.
Contents
1. Scope and intended use
DVR Time Traveler is an investigative aid and a time-base certification instrument. It performs deterministic arithmetic on time values supplied by an officer and produces a structured PDF report documenting the calculation, the inputs, the device on which the calculation was performed, and the time at which the calculation was performed.
Used this way, the report certifies the time base of the DVR under examination — establishing, on the record, whether that recorder's internal clock was behind, accurate, or ahead of true time at the moment of examination. This applies to any DVR that keeps an internal clock, including recorders whose clock is already correct: the report documents that the clock was verified and found accurate, rather than leaving that assumption unstated.
The application does not ingest video, decode video timestamps, establish chain of custody for third-party media (such as the underlying DVR recording), or assert that the underlying DVR recording is authentic. Those determinations remain the responsibility of the investigator, the seizing agency, and the trier of fact. The application does, however, produce two categories of app-generated artifacts — PDF reports and case photos — each of which carries its own tamper-evidence, time-attestation, and device-binding metadata described in this document (see §4.5 for PDF document properties and §6.5 for photo EXIF attestation).
This whitepaper describes the controls that allow a third party to independently verify, weeks or years after the fact, that:
- The PDF in question was produced by DVR Time Traveler.
- It has not been altered since the moment of generation.
- The hash of its content existed at or before a specific instant in time, attested by an independent Time-Stamping Authority.
- The app clock used to perform the calculation was, within a stated margin, accurate at the time of generation.
2. Problem statement
Surveillance Digital Video Recorders (DVRs) commonly run free-running real-time clocks that are not synchronized to authoritative time sources. Drift of seconds per day is normal; drift of hours or days is not unusual for DVRs that have been re-installed without re-configuration, lost power for extended periods, or whose time zone was set incorrectly at installation.
Investigators must therefore translate between two clocks: the inaccurate DVR clock and a reliable "real-world" clock. Errors in this translation propagate into incident reports, statements of probable cause, witness interviews, and ultimately trial exhibits.
DVR Time Traveler eliminates manual arithmetic by computing the translation, formalizing the inputs, and producing a self-describing artifact (the PDF report) that documents both the result and the conditions under which it was produced. Where the DVR clock is found to be accurate, the same artifact serves as a certification of that fact — a documented, independently verifiable record that the recorder's time base was examined and confirmed, not merely presumed.
3. The mathematics
The app does the same time arithmetic an officer would do by hand — subtracting one clock from another — but without the risk of a manual mistake. It works in a single universal time standard internally, so daylight saving, leap years, and crossing midnight or New Year are all handled automatically.
The application supports three core calculations, all performed in Coordinated Universal Time (UTC) internally:
3.1 Time difference
Given an actual real-world time T_real and the time displayed by the DVR T_dvr at the same physical instant:
delta = T_real − T_dvr
Where delta may be positive (DVR is behind) or negative (DVR is ahead). The absolute value is decomposed into days, hours, minutes, and seconds for display.
3.2 Target DVR time for an event
Given the calculated delta and the real-world time of an event of interest T_event:
T_dvr_target = T_event − delta
This produces the time the investigator should seek on the DVR in order to view the event.
3.3 Retention horizon
Given a current real-world date T_now and the configured retention period R (in days):
T_retention_end = T_now + R days
and conversely the earliest still-recoverable date is T_now − R days.
3.4 Edge cases handled
- Daylight saving transitions. Calculations are performed on UTC, so spring-forward and fall-back are inherently respected. Display formatting uses the device's locale to render the correct local time.
- Leap years. Day-in-month bounds are validated per month per year (e.g., February 29 only allowed in leap years).
- Cross-day deltas. Differences spanning midnight are handled correctly by operating on absolute timestamps, not on time-of-day strings.
- Cross-year deltas. Same.
- Time-zone differences. The device captures its own time zone offset and includes it in both the computation and the report.
4. Tamper-Evidence Checksum
Think of this as a tamper-evident seal. The app turns every value on the report — the times and numbers, and the case information such as the case number, DVR address, DVR identification and officer name — into a unique fingerprint. If anyone changes even one character of any of those fields, the fingerprint no longer matches — so an alteration is easy to detect. (Proof of who created the report, and when, comes from the independent timestamp in Section 5.)
Every PDF report contains a Tamper-Evidence Checksum, a 64-character hexadecimal value derived from an HMAC-SHA256 keyed message authentication code (RFC 2104) computed over the canonical representation of every numeric field displayed on the report, plus the officer's badge identifier, the device identifier, the report date, the application version, and the administrative case fields (case number, DVR address, DVR identification, officer name, department and unit).
4.1 Inputs
The following fields are serialized, in alphabetical order of key, as a deterministic JSON string. That string is the HMAC message; a fixed application secret is the HMAC key:
- Device identifier (UUID derived from hardware identifiers)
- Application version
- Officer badge identifier (numeric portion only)
- Report generation date
- Correlation timestamp (the moment
deltawas captured) - DVR date and time at correlation
- Event date and time
- Final (target) date and time on the DVR
- Computed time difference (decomposed)
- Retention end date
- Retention period (days)
- Case number (normalized text)
- DVR address / location (normalized text)
- DVR identification (normalized text)
- Officer name (normalized text)
- Department / agency (normalized text)
- Unit / division (normalized text)
Numeric and date/time fields are reduced to their digits (normalized to the ISO 8601 ordering) before hashing, so the code is independent of the device's display language and regional format. The administrative case fields are normalized as text — surrounding whitespace is collapsed and the value is upper-cased — so incidental spacing or capitalization differences do not affect the code while any substantive change does.
4.2 Algorithm
code = HMAC-SHA256( key = application_secret, message = JSON(fields, sorted_keys) )
HMAC-SHA256 is the standard keyed message authentication code defined in RFC 2104 and FIPS 198-1. The first 12 hexadecimal characters of code form the human-readable Document ID, prefixed DVRTT-. The full 64-character value is displayed in the PDF for byte-level verification.
4.3 Properties and intended assurance
- Tamper-evidence. Modification of any included field will, with overwhelming probability, change the code. A verifier with the same application secret can re-compute the code from the displayed fields and detect any alteration.
- Determinism. Identical inputs always produce identical codes. This makes the code a stable reference across re-prints.
- Honest non-property. The code is a keyed message authentication code (HMAC), not a public-key digital signature. The application secret is embedded in the application binary. A sufficiently motivated party with a copy of the application can in principle compute valid codes for arbitrary inputs. The code therefore provides tamper-evidence, not non-repudiation.
- Mitigation. Non-repudiation is provided by the independent RFC 3161 Trusted Timestamp described in §5, which does not rely on any application-embedded secret.
4.4 Report Verification Service
SDTech offers a professional Report Verification Service for agencies and legal professionals who require a formal confirmation that a DVR Time Traveler report has not been altered. Upon request, SDTech will re-derive the Tamper-Evidence Checksum from the fields visible on the report and confirm whether the code matches — providing a signed attestation suitable for court proceedings. Because SDTech develops the application, this is a first-party expert verification rather than an independent one; for fully independent verification, any third party can re-compute the open HMAC-SHA256 method described above, and the RFC 3161 trusted timestamp in §5 is issued by an independent authority.
To request verification or learn more about this service, use our secure certificate request page.
4.5 PDF document properties
Every PDF report carries built-in "document properties" — the fields any PDF reader shows in its properties panel — that identify the app that produced it, the type of report, and the exact moment of creation. This makes the source of the document self-evident even before any content is examined.
In addition to the Tamper-Evidence Checksum described above, every PDF report carries a structured PDF Info Dictionary populated at generation time. These fields are viewable in any PDF reader's document properties panel and provide an independent, easily-inspected layer of attestation about the document's origin:
| PDF property | Value |
|---|---|
Title | DVRTT Report - <Officer Name> - Case <Number> |
Author | DVR Time Traveler |
Subject | DVR Time Correlation Report - Law Enforcement or DVR Time Correlation Report - Private Investigation (mode-dependent) |
Creator | DVR Time Traveler v<version> |
Producer | DVR Time Traveler v<version> |
Keywords | DVR, time correlation, forensic |
CreationDate | Session-locked verified time from the same clock used elsewhere in the report (see §6) |
ModDate | Same session-locked verified moment as CreationDate |
The CreationDate and ModDate fields are populated
from timeService.getNowSync() — the same session-locked,
monotonic-anchored clock that drives every other timestamp on the
report — rather than from the operating system's default (which
would read the device clock again at the moment the PDF renderer wrote
the file, without the anchoring that protects against mid-session clock
changes). This alignment means the PDF's internal CreationDate matches the
report's on-page “Correlation performed at” timestamp and the
filename of any photo taken in the same session, providing a coherent
temporal record across all app-generated artifacts.
These properties are not covered by the Tamper-Evidence Checksum (which hashes only the displayed report data). A defense-side examiner can freely edit the Info Dictionary using standard tools; if they do, the Trusted Timestamp in §5 will still bind the original hash to the original moment of issuance. The Info Dictionary is presented here as informational metadata that makes provenance immediately visible, not as a cryptographic guarantee.
5. RFC 3161 Trusted Timestamps
An independent, outside company (a Time-Stamping Authority) certifies the exact moment the report existed — like a notary date-stamp that nobody, including SDTech, can fake or back-date. Only a privacy-safe fingerprint of the report is sent out; the report's contents never leave the device.
Beginning with version 10.2.5, every PDF report optionally includes a Trusted Timestamp conforming to RFC 3161 (Internet X.509 Public Key Infrastructure Time-Stamp Protocol).
5.1 Privacy-preserving design
The application computes a SHA-256 hash of the canonical content described
in §4 and transmits only that hash to the SDTech license server.
The server forwards an RFC 3161 TimeStampReq containing the
hash to a configured Time-Stamping Authority (TSA). The TSA does not see
the original content. The original content never leaves the device.
5.2 Trust chain
- The TSA issues a
TimeStampToken, which is a CMSSignedDatastructure containing aTSTInfofield that asserts the hash, the policy under which the timestamp was issued, and a trusted time. The token is signed with the TSA's private key. - The TSA's signing certificate chains to a publicly trusted root Certificate Authority.
- The license server stores the token, the original hash, the TSA name, the issued time, and the requesting context in a tamper-evident Cloudflare D1 record. Each record is given a stable, URL-safe Token ID.
- The PDF embeds the Token ID, the issued time, the TSA name, the content hash, and a public verification URL.
- Anyone may later fetch the verification URL to retrieve the metadata
and (with
?include_raw=1) the original DER-encodedTimeStampTokenfor cryptographic verification using standard tools (OpenSSLts -verify, RFC 3161-compliant libraries, etc.).
5.3 Configured Time-Stamping Authorities
| Provider | Default | Audited | Used for |
|---|---|---|---|
| FreeTSA.org | Yes | No (community-operated, public CA) | Standard accounts |
| DigiCert | Optional | Yes (WebTrust audited) | Agency tier |
| Sectigo | Optional | Yes | Configurable per deployment |
5.4 What a Trusted Timestamp proves
- That the document hash existed at or before the asserted issued time.
- That the asserted time was attested by a third party operating outside SDTech's control.
- That the document content has not been altered since the timestamp was issued (because any change to the content would change the hash).
5.5 What a Trusted Timestamp does not prove
- It does not authenticate the identity of the human who produced the report.
- It does not assert that the underlying inputs (the DVR time, the real-world event time) were truthful or accurate. Those determinations remain a question for the trier of fact.
- It does not assert that the app clock displayed in the report was correct. That assurance is provided independently by §6.
6. Time Source Attestation
At the moment the report is made, the app checks its own clock against several independent internet time sources (Cloudflare, Google, Apple, Microsoft, Amazon) and records how far off it was. A near-zero result is contemporaneous evidence that the clock was accurate. If the device is offline, the app says so plainly and the officer confirms the clock against an outside reference first.
The application uses a verified device clock for all report
timestamps and calculations. On the warning page at session start, the
device clock is compared against a multi-source Internet time consensus
(see §6.1–§6.2). When the measured drift is within ±2
seconds of the consensus — the noise floor of HTTP-Date
header measurement, and finer than the accuracy the app can meaningfully
claim — the device clock is accepted as-is: no offset is applied,
because at that resolution the operating system's own time source
(NITZ / GNSS / NTP) is more accurate than any HTTP-based correction the
app could compute. The accepted clock is then session-locked and
accessed exclusively through timeService.getNowSync(), which
anchors it to performance.now() (a monotonic counter) so
that mid-session clock changes are detected and handled — see
§6.6 for the precise behaviour of backward and forward
manipulations, and how the app distinguishes legitimate device sleep
from a malicious forward jump. This session-locked verified clock
drives the PDF's own CreationDate (§4.5), the
“Correlation performed at” timestamp printed on the recto, and
the capture time of any in-app photo (§6.5). If measured drift is
≥ 2 seconds, the user is not permitted to proceed until they
re-verify, correct the device clock, or explicitly acknowledge and
proceed on the officer's own attestation. At report generation the
application performs a second, independent Time Source Attestation
— it re-queries the same uncorrelated Internet time sources,
computes a consensus and records the drift between the session-locked
app clock and that consensus — providing contemporaneous,
third-party-verifiable evidence of app clock accuracy at the moment of
report generation.
If the device is offline at the time of generation, no external time sources can be queried and the attestation is marked UNAVAILABLE — the application falls back to the device clock for calculations and prominently displays a cloud-off icon on the report. In this scenario, the officer has already confirmed on the warning page — by acknowledging the labelled checkbox “I have verified that automatic time is enabled and accept the above conditions” — that the device's Automatic Time setting is active and that the three time-integrity conditions listed on the same page have been read and accepted. Best practice is to additionally cross-check the device clock against an independent external time reference (radio-controlled watch, second device, dispatch timestamp, or a broadcast time signal) and to photograph that reference with the in-app camera so that the resulting JPEG carries the same session-locked verified time (labelled “NTP-verified” or “device clock” per §6.5) in its EXIF metadata. The report's offline page explicitly documents this state, providing a documented chain of responsibility for clock accuracy even without automated attestation. The attestation result is included verbatim in the PDF.
Why automatic time is physically necessary. On both iOS and
Android, the manual time-setting interface provides controls for hours
and minutes only — there is no seconds selector. When a user sets
the clock manually, the seconds component is either reset to
:00 or left at its current arbitrary value, depending on
the OS version. This means a manually configured clock will always carry
an uncontrollable offset of up to 59 seconds relative to true time.
Only the operating system’s automatic time synchronization (via
NITZ, GNSS, or NTP) can set the seconds precisely. This is why the
app’s first condition on the warning page is confirmation that
automatic time is enabled: it is not merely a recommendation but a
physical prerequisite for second-level accuracy.
6.1 Sources queried
The current source list (subject to evolution) is:
- Cloudflare (HTTP
Dateheader oncdn-cgi/trace) - Google (HTTP
Dateheader ongenerate_204) - Apple (HTTP
Dateheader on the test endpoint) - Microsoft (HTTP
Dateheader on Bing) - Amazon (HTTP
Dateheader on AWS CloudFront)
Sources are operated by independent organizations across multiple jurisdictions. A single compromised source cannot mislead the consensus.
6.2 Method
For each source, the application records:
- The local time immediately before the request (
t_start); - The local time immediately after the response (
t_end); - The time reported by the source (
t_reported).
It then applies the standard SNTP half-RTT correction:
t_corrected = t_reported − (t_end − t_start) / 2
midpoint = (t_start + t_end) / 2
drift = t_corrected − midpoint
The consensus offset is the median of all successful samples; the spread is the sample standard deviation.
6.3 What is reported in the PDF
The attestation block printed on the report contains:
- A plain-language summary line stating how far the app clock was from the consensus — expressed in milliseconds when the drift is under one second, or in seconds otherwise (e.g., “App clock within 250 ms of 4-source consensus”).
- A per-source table listing every source queried, with a success/failure marker (✓ / ✗), the source name, the time it reported (UTC, round-trip-corrected) — or a failure reason such as “Timed out” or “Unreachable” — and that source's individual drift in milliseconds.
- A metadata line showing the overall status, the consensus time (UTC), the sample spread (1σ) in milliseconds, and the run window (start → finish timestamps).
- The overall status: OK (≥ 2 sources), DEGRADED (1 source), UNAVAILABLE (0 sources).
6.4 Resolution and fitness for purpose
The HTTP Date header has whole-second resolution under
RFC 7231. A single
sample therefore carries on the order of ±1–2 seconds of
measurement error (one-second quantization plus network round-trip
asymmetry); taking the median across several independent operators removes
per-source jitter, while the absolute floor remains roughly ±1 second.
This is adequate for the intended use case: confirming that the app clock used
to compute the report's user-facing timestamps was, at the moment of
generation, accurate to seconds, not microseconds. Higher-precision
NTP-over-UDP is reserved for future native module work and is not required
for this purpose.
6.5 Photo capture and EXIF attestation
When a photo is taken with the app, the app writes the same session-locked verified time and the same device identifier into the photo's own metadata. That means a photo of a DVR screen, a photo of an external clock used to confirm device time, and the PDF report from the same session can all be tied back to the same device and the same verified moment.
Case photos captured through the in-app camera are treated as first-class
evidentiary artifacts. At the instant the shutter is pressed —
before the operating system finishes encoding the JPEG — the
app reads the current time from timeService.getNowSync()
(the same session-locked, monotonic-anchored verified clock used
everywhere else in the report). This capture-time value drives both the
photo's filename and the following EXIF tags, written in-place
after capture:
| EXIF tag | Value |
|---|---|
Software (0th IFD) | DVR Time Traveler v<version> |
ImageDescription (0th IFD) | DVR Time Traveler or DVR Time Traveler - Case <Number> |
DateTime (0th IFD) | Session-locked verified capture time (YYYY:MM:DD HH:MM:SS) |
DateTimeOriginal (Exif IFD) | Same session-locked verified capture time |
DateTimeDigitized (Exif IFD) | Same session-locked verified capture time |
UserComment (Exif IFD) | DVR Time Traveler | Time: <source> | <timestamp>[ - Case <Number>] | Device: <Device ID> |
The time source status written into UserComment is
one of three literal values:
NTP-verified— the device clock was verified to be within ±2 seconds of the multi-source network time consensus described in §6.1–§6.4, then session-locked, before the photo was taken.device clock— the app was operating offline (or in a state where the officer explicitly acknowledged residual drift), and the officer confirmed device clock accuracy against an independent external reference before proceeding, as described in §6.NTP-verified (checkpoint pending)ordevice clock (checkpoint pending)— the photo was taken during the brief window (~2 seconds) between the app returning to the foreground and the completion of the foreground time-verification checkpoint (§6.6). The parenthetical suffix is transparent about the fact that the checkpoint had not yet confirmed the anchor when the shutter fired.
The Device ID written into UserComment is the
same hardware-derived identifier that is included as one of the 17 fields
covered by the Tamper-Evidence Checksum on any PDF report generated on
the same device (§4.1). This is the mechanism that ties a photo to
the PDF report(s) produced on the same device: an examiner comparing
Device in a photo's UserComment against the
Device identifier line printed on a PDF report can confirm
that both artifacts originated from the same DVR Time Traveler
installation.
EXIF fields are readable by any standard tool —
exiftool, most image editors, and every operating system's
file-properties dialog — requiring no cooperation from SDTech.
The filename timestamp and the EXIF DateTimeOriginal are
populated from the same value, so mismatch between them is a positive
indicator of post-hoc manipulation.
Burned-in timestamp. In addition to the machine-readable EXIF
metadata, a visible timestamp is rendered directly into the image
pixels at full sensor resolution (bottom-right corner, monospace font
on a semi-transparent background). The burned-in text reads
DVR Time Traveler (yellow) on one line and the ISO-format
capture time YYYY-MM-DD HH:MM:SS (white) on
the line below. This ensures the verified capture time is visible
when the photo is printed, projected, or viewed as a standalone file
without EXIF-aware software. ISO 8601 format is used regardless of
the officer's locale setting to ensure the date is unambiguous in
cross-jurisdictional proceedings.
Sub-second timing. The capture timestamp is read from
the verified clock at the instant the shutter button is pressed,
before the camera sensor begins exposure. All three
representations — filename, EXIF, and burned-in text —
truncate to whole seconds and are derived from the same value.
On most devices the burned-in timestamp matches the scene
content exactly. On older or slower hardware, the sensor
exposure and JPEG encoding may take slightly longer, and in
rare cases a clock visible in the scene could differ by one
second from the burned-in timestamp (e.g., stamp reads
14:35:01 while the scene shows
14:35:02). This is a hardware-dependent edge case,
not a systematic offset; the timestamp always records the
decision to capture.
EXIF metadata is not covered by the Tamper-Evidence Checksum
(which secures only the PDF report fields). If the JPEG file is modified
after capture, the standard defenses are (i) the SHA-256 hash of the
original file, computed on transfer to case management, and (ii) the
session-locked verified filename which is set at capture and cannot be
forged without changing the file the operating system wrote. If the
photo is
later attached to a PDF report, the report's Trusted Timestamp (§5)
binds the report content but not the attached photo files — the
photo's own EXIF DateTimeOriginal is what carries the
contemporaneous time record for the image itself.
6.6 Mid-session clock-change detection
To change the phone's clock, the user has to leave the app and open Settings. Every time the app comes back to the foreground, it automatically runs a fresh network time check. If the clock was changed while the app was in the background, the check catches it and tells the officer. There are no silent bypasses — the officer must complete a full re-verification before continuing. Legitimate device sleep (pocket, screen off) passes the check silently because the network agrees that the correct time hasn't changed.
Once the session is locked (§6), every
AppState → 'active' transition (the app returning
to the foreground after being backgrounded or after the device wakes from sleep)
triggers a foreground checkpoint:
- A checkpoint-pending flag is set immediately. Any photo or
PDF saved during this brief window (~2 seconds) carries the
suffix
(checkpoint pending)in its metadata (§6.5). - The session lock is temporarily released and a fresh NTP sync runs against the same multi-source consensus used at session start (§6.1–§6.4). The sync writes a new offset and re-anchors the monotonic clock.
- The session is re-locked and the checkpoint-pending flag is cleared.
- The drift — the difference between how much the
device’s wall clock advanced during the background window
and how much network reality advanced during the same window —
is computed.
- If the drift is < 2 seconds (within HTTP Date-header measurement noise), the anchor refresh is silent. This is the common case: the device was sleeping, its OS-level time sync kept the clock accurate, and no user prompt is needed.
- If the drift is ≥ 2 seconds, a Background Time Check modal is presented with the exact number of seconds the device clock diverged. The only option is Full re-verification — the officer is returned to the Warning Page to re-read the three conditions and formally re-attest via the checkbox. There is no shortcut; every detected clock change requires the same commitment as starting a new session.
- If the device is offline and the NTP sync fails, the checkpoint is a no-op: the anchor is not changed, the session lock remains in place, and the next successful checkpoint (when connectivity returns) will surface any discrepancy.
Why this is sufficient. On both iOS and Android, the date/time
settings are inside Settings.app / System Settings, which is a
separate application. Opening it backgrounds DVR Time Traveler.
Returning to DVR Time Traveler produces an
AppState → 'active' event. Therefore
every tampering opportunity is bookended by exactly one
checkpoint. No threshold tuning, direction heuristics, or
sleep-vs-tamper disambiguation is required.
Inline protection while foregrounded. While the app is in the
foreground, getNowSync() still reads
performance.now() alongside Date.now()
on every call. If the device clock deviates by more than
5 seconds from the monotonic estimate, the internal
timeOffset is silently corrected so that
timestamps continue to advance monotonically from the
session-locked anchor. This protects against clock changes
made via ADB, rooted shells, or other non-Settings paths
that do not background the app.
Combined with the RFC 3161 Trusted Timestamp (§5), which is issued by a third-party TSA that no device-clock manipulation can affect, the forensic chain is complete:
- Report generation timestamp comes from the session-locked verified clock (§6);
- Any mid-session tampering is either corrected inline (device-clock change while foregrounded) or surfaced to the officer at the checkpoint (clock change while backgrounded);
- The Trusted Timestamp independently proves when the report's content existed, regardless of any device-side clock state.
7. Verification procedure
Any party may independently verify a DVR Time Traveler PDF using only standard, publicly available tools.
7.1 Verify the Tamper-Evidence Checksum
- Read all numeric fields from the PDF as displayed.
- Re-compute the HMAC-SHA256 code using the canonical input construction described in §4 and the HMAC key documented in the application source. (SDTech also offers a paid first-party verification service — see §4.4 — but no cooperation from SDTech is required for third-party verification.)
- Compare to the value printed on the PDF. Any mismatch indicates alteration.
7.2 Verify the Trusted Timestamp metadata
curl https://verify.sdtech.app/api/v1/timestamp/verify/<TOKEN_ID>
The response includes the original hash, the TSA, the issued time, and the request context. Compare the hash to the one printed on the PDF.
7.3 Cryptographically verify the Trusted Timestamp token
# 1. Fetch the raw RFC 3161 token (base64)
curl 'https://verify.sdtech.app/api/v1/timestamp/verify/<TOKEN_ID>?include_raw=1' \
| jq -r .tokenB64 | base64 -d > token.tsr
# 2. Verify against the document hash (TSA root cert from FreeTSA / DigiCert as applicable)
openssl ts -verify -in token.tsr -digest <HASH_HEX> \
-CAfile tsa-ca.pem
An OK result confirms that the asserted hash existed at or before the timestamp issued time and that the token was issued by the named TSA.
7.4 Verify the Time Source Attestation
The attestation is reproducible in principle but not in fact (the queried sources do not retain historical responses). The attestation block in the PDF is therefore evaluated as contemporaneous evidence of clock accuracy at the time of report generation, not as a re-runnable test.
7.5 Verification portal and offline report timestamping
SDTech provides a public verification portal at verify.sdtech.app. Any party can paste a token ID (ts_...) or a full verification URL to look up a timestamp record.
For reports generated offline (no trusted timestamp was obtained at generation time), an offline report timestamping tool is available at verify.sdtech.app/api/v1/timestamp/offline. The tool accepts the document’s SHA-256 hash (printed on the offline attestation page) and submits it to the same independent third-party TSA used for online reports. The resulting RFC 3161 token cryptographically binds the document hash to the moment of submission, producing a printable verification certificate identical to the one provided automatically when the device is online. A pre-filled link to this tool is embedded directly in every offline report’s forensic attestation page.
7.6 Verify PDF document properties
The Info Dictionary (§4.5) is viewable in any PDF reader (Adobe Acrobat, macOS Preview, Windows PDF viewers) via File → Properties, or from the command line:
exiftool -PDF:all report.pdf
# or
pdfinfo report.pdf
Expected values:
Author = DVR Time Traveler,
Creator/Producer = DVR Time Traveler v<version>,
Subject matches the report type
(Law Enforcement or Private Investigation).
The CreationDate should match the “Correlation performed
at” timestamp printed on the recto of the report. A mismatch is not
proof of tampering (the Info Dictionary is not signed), but it is worth
investigating alongside the Tamper-Evidence Checksum.
7.7 Verify photo EXIF metadata
For any JPEG captured with the in-app camera (§6.5), the EXIF tags
can be inspected with exiftool:
exiftool -Software -ImageDescription -DateTimeOriginal \
-DateTimeDigitized -UserComment photo.jpg
Expected values:
Softwarebegins withDVR Time Traveler.DateTimeOriginalmatches the timestamp embedded in the filename (e.g., filename...T14-35-22.jpg→ EXIF14:35:22). A mismatch indicates the file was re-encoded or the EXIF was rewritten.UserCommentcontains a time-source status (NTP-verifiedordevice clock) and aDevice: <ID>field. The Device ID should match theDevice identifierprinted on any PDF report from the same session.
EXIF verification is complementary to, not a substitute for, the PDF report's Tamper-Evidence Checksum and Trusted Timestamp. It is most valuable when investigating whether a photo attached to a report was actually taken by the same device that generated the report, or when authenticating a photo that was shared separately from its report.
8. Limitations and honest caveats
- Investigative aid, not original evidence. The PDF is a derived artifact. The original evidence remains the surveillance recording itself.
- Garbage in, garbage out. The mathematics is exact; the inputs are not. If the officer enters the wrong DVR time at correlation, the result will be precisely wrong.
- Tamper-Evidence Checksum is a keyed MAC. HMAC-SHA256 provides tamper-evidence but not non-repudiation. Non-repudiation comes from the RFC 3161 timestamp.
- RFC 3161 timestamps depend on the TSA. If the issuing TSA's signing key is later revoked or its operations called into question, the assurance value of timestamps issued during the affected period must be re-evaluated. SDTech monitors TSA status and may issue advisories.
- Time Source Attestation is one-shot. The attestation reflects the moment of report generation, not continuous clock health.
- Network dependence. If the device is offline at the time of generation, the Trusted Timestamp will be omitted (the PDF clearly states this) and the Time Source Attestation will be marked UNAVAILABLE. In this case the officer confirms device clock accuracy against an external time reference before proceeding; the report documents this officer-verified state via the cloud-off icon and a dedicated offline attestation page. A trusted timestamp can be obtained after the fact using the tool at verify.sdtech.app (see §7.5).
- Application secret in binary. The HMAC key is recoverable from the application binary. This is documented; the design relies on RFC 3161 for trust beyond tamper-evidence.
- PDF Info Dictionary and photo EXIF are informational, not cryptographic. The PDF properties (§4.5) and photo EXIF tags (§6.5) make provenance immediately visible in any standard reader, but they are not covered by the Tamper-Evidence Checksum. A knowledgeable adversary can rewrite them with off-the-shelf tools. Their evidentiary weight comes from their consistency with the HMAC-covered fields on the report and, for photos, with the filename that was set at the shutter instant.
9. Anticipated cross-examination Q&A
Q. "Could the officer have manipulated this report?"
An officer who modifies the displayed fields without re-generating the report will invalidate the Tamper-Evidence Checksum; the modification will be detectable by re-computation. An officer who re-generates the report after modification will produce a new RFC 3161 timestamp with a later issued time, which will be evident on the face of the document.
Q. "How do we know the app clock was right when this was generated?"
The Time Source Attestation block in the PDF records the drift between the app's session-locked verified clock and the median of multiple independent Internet time sources at the moment of generation. A drift value within seconds of zero is contemporaneous evidence of an accurate clock. Because the app anchors its session-locked time to performance.now() (a monotonic counter), the attestation remains meaningful even if the device's system clock is changed mid-session — the anchoring makes the change detectable.
Q. "How do we know SDTech didn't fabricate this timestamp?"
The Trusted Timestamp is signed by an external Time-Stamping Authority — FreeTSA, DigiCert, or Sectigo, depending on configuration — using a key SDTech does not possess. SDTech cannot forge a valid token. The token is independently verifiable using OpenSSL or any RFC 3161 library.
Q. "What if the TSA was compromised?"
A compromise of a public TSA would be a major incident affecting the entire industry. SDTech monitors public TSA security advisories and would issue a corresponding advisory affecting reports generated during any affected window. Reports may be re-anchored against an alternative TSA on request.
Q. "Is this app certified for court use?"
No software is "certified" for court use in any general sense; admissibility is decided case by case by the court of competent jurisdiction. What the application provides is a sound technical foundation for that determination: every report carries a Tamper-Evidence Checksum (§4), an independent RFC 3161 trusted timestamp from an outside authority (§5), and a contemporaneous record of clock accuracy (§6) — all verifiable by any third party using standard, publicly available tools. Courts across jurisdictions routinely accept timestamped, tamper-evident digital evidence when it is properly introduced and supported by testimony. This whitepaper and the open verification procedure are intended to support that introduction.
Q. "Could the officer have fabricated the entire scenario?"
The application does not, and cannot, defend against an officer who knowingly enters false inputs. That scenario is identical to a hand-written calculation containing knowingly false figures. The application's role is to ensure that, given the inputs as recorded, the arithmetic is correct, the result is preserved unaltered, and the generation event is independently anchored in time.
10. Standards and references
- RFC 3161 — Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP)
- RFC 5816 — ESSCertIDv2 update for RFC 3161
- FIPS 180-4 — Secure Hash Standard (SHA-256)
- RFC 2104 — HMAC: Keyed-Hashing for Message Authentication
- FIPS 198-1 — The Keyed-Hash Message Authentication Code (HMAC)
- FIPS 197 — Advanced Encryption Standard (AES)
- NIST SP 800-171 r2 — Protecting Controlled Unclassified Information
- NIST SP 800-88 r1 — Guidelines for Media Sanitization
- FBI CJIS Security Policy v6.0 (mapped in the SDTech compliance package, available on request)
- RFC 8446 — TLS 1.3