Someone sends you a file and a small companion with a .tsr extension, and says the pair proves the file existed on a certain date. Or you hold timestamped evidence of your own, and you want to know it will survive the other side's expert. Either way the question is the same: does this timestamp actually check out?
You don't need to trust the person who sent it, or the service that made it. An RFC 3161 timestamp can be verified with OpenSSL, a free tool already installed on most Linux systems. This guide covers what the timestamp proves, how to read one, and how to verify it, including what to do when verification fails.
What a timestamp proves, and what it doesn't
RFC 3161 is the internet standard for trusted timestamps. In its own words, a time-stamping service "supports assertions of proof that a datum existed before a particular time".
It works on a fingerprint, not the file. You compute a hash of the file, usually SHA-256, and send only that to a timestamping authority (TSA). The standard requires the TSA "not to examine the imprint being time-stamped in any way (other than to check its length)", and not to put any identification of the requester in the token. The TSA adds the time, a unique serial number and the identifier of its policy, signs the lot with a key reserved for timestamping, and returns it. That signed object is the token.
So a token that verifies proves one thing: a file with exactly this SHA-256 existed no later than the time in the token, according to the TSA that signed it.
It does not prove:
- What the file shows is true. A timestamped capture of a web page proves the capture existed at that time. It says nothing about where the page came from. That depends on how the capture was made, which we cover in how to preserve a web page as evidence.
- When the file was created. Only that it existed by then. It may be older.
- Who made it. The token deliberately carries no identity of the requester.
- More than the TSA's honesty. The proof is as good as the authority behind it and the security of its signing key.
How much legal weight a timestamp carries depends on where you are. In the EU, Article 41 of the eIDAS Regulation says an electronic timestamp "shall not be denied legal effect and admissibility as evidence in legal proceedings solely on the grounds that it is in an electronic form or that it does not meet the requirements of the qualified electronic time stamp". Only a qualified timestamp gets a presumption that its date and time are accurate and that the data it is bound to is intact. The UK kept the same two rules in its retained version of the regulation. An ordinary RFC 3161 token, even from a well-known authority, is not qualified. It is evidence to be weighed like any other, and verifying it is part of showing it deserves weight.
What you need
- The file exactly as it was timestamped. Byte for byte. A copy that was opened and re-saved, converted to PDF or passed through an email client that changed its line endings will have a different hash, and it will fail.
- The token, usually a
.tsrfile. - OpenSSL. Run
openssl versionto check. The commands below are for OpenSSL 3. - A file of trusted root certificates. On Debian and Ubuntu this is
/etc/ssl/certs/ca-certificates.crt.
Practise on a timestamp of your own
If you don't have a token to hand, make one. DigiCert's RFC 3161 server is at http://timestamp.digicert.com, and a request takes two commands.
Create a request for any file. -cert asks the TSA to include its signing certificate in the reply, which you will need later:
openssl ts -query -data report.pdf -sha256 -cert -out report.tsq
Send it over HTTP with the content type the standard defines:
curl -s -H "Content-Type: application/timestamp-query" \
--data-binary @report.tsq -o report.tsr http://timestamp.digicert.com
report.tsr is now a full timestamp response for report.pdf. The file itself never left your machine.
Verifying a timestamp, step by step
1. Work out what kind of file you have
A .tsr can hold one of two things: a full response, which wraps the token with a status, or the bare token on its own. Services that store timestamps for later often keep only the token. OpenSSL needs to know which, and the -token_in option tells it the input is a token.
Try reading it as a response first. If OpenSSL reports an error parsing it, add -token_in to this and every later command.
2. Read what the token says
openssl ts -reply -in report.tsr -text
The fields that matter:
- Status: for a full response, it should say the request was granted. A token file has no status.
- Time stamp: the time the TSA created the token, in UTC (shown as GMT).
- Hash Algorithm and Message data: the algorithm used and the fingerprint that was timestamped.
- Serial number: unique to this token. Quote it if you ever need to ask the TSA about it.
- Policy OID: identifies the TSA policy it was issued under.
- Accuracy: how far the time may be out, if the TSA states it.
- Nonce: a random number from the request, used to match the reply to it.
3. Hash the file and compare
openssl dgst -sha256 report.pdf
The 64 hexadecimal characters it prints should match the Message data in step 2. OpenSSL prints the Message data as a hex dump across several lines, so compare it carefully. The next step compares it for you, but seeing the match with your own eyes makes it easier to explain later.
4. Verify the signature, the certificate and the file together
openssl ts -verify -data report.pdf -in report.tsr \
-CAfile /etc/ssl/certs/ca-certificates.crt
OpenSSL hashes the file again and checks that the fingerprint matches the one in the token. It checks that the token has exactly one signer and that the signature is valid. It then builds a chain from the signing certificate to one of your trusted roots, which includes checking that the certificate is issued for timestamping. It prints Verification: OK only if all of that holds.
If you still have the original request, verify against it instead with -queryfile report.tsq in place of -data report.pdf. That also checks that the nonce and policy match what was asked for, which shows this reply answers that request and is not an older one being reused.
When verification fails
The error usually tells you which check failed.
message imprint mismatch: the file is not the one that was timestamped. Find the original. A file that has been "tidied up", re-exported or re-saved won't match, and nothing will make it match.unable to get local issuer certificate: OpenSSL could not build the chain to a trusted root. Either the token did not include the TSA's certificates, or an intermediate is missing. Download the TSA's certificate chain from its website and pass it with-untrusted chain.pem. DigiCert publishes its chain files on the same page as its timestamp address.certificate has expired: see below. This does not mean the timestamp is worthless.- An error parsing the input: you have a token and forgot
-token_in, or the other way round.
Tokens outlive their certificates
A TSA's signing certificate is valid for a limited period. After it expires, a plain -verify fails, because OpenSSL checks every certificate against today's date by default.
The expiry doesn't cancel what the token proved. -attime tells OpenSSL to check the chain as of a given moment, given in seconds since 1 January 1970. To check a token as it stood on 1 January 2030 (the date command here is the GNU version found on Linux):
openssl ts -verify -data report.pdf -in report.tsr \
-CAfile /etc/ssl/certs/ca-certificates.crt \
-attime $(date -d 2030-01-01 +%s)
That shows the token was sound at that moment. To show it to someone else years later, you need evidence that the token itself existed while its certificates were still valid. RFC 3161 anticipates this: its security considerations note that a token may need to be timestamped again to keep its value beyond the lifetime of the original certificate. Each new timestamp covers the previous token, forming a chain in which every link can be verified with the same command.
Revocation is the other exception. If a TSA's signing key is compromised, the RFC says any token signed with that key "cannot be trusted anymore", whenever it was made. A revocation for any other reason leaves tokens signed before it valid. For evidence meant to last, keep the certificate authority's revocation list from around the time of each timestamp alongside it.
How Archivepanel handles it
Every page we capture is saved as one self-contained HTML file, and as the capture completes, DigiCert timestamps that file's SHA-256 under RFC 3161. Only the fingerprint leaves our service. Before storing a token we check that it covers the right digest, answers our request, carries a valid signature and chains to a public root through a certificate issued for timestamping.
You can download the document and its token from the record page and run the verification above on your own machine, without an account. In the year before the certificates behind a token expire, we renew the timestamp and keep the revocation list from that time, so the chain stays checkable. The record page prints the OpenSSL commands with the file names and times filled in.
Our timestamps are not eIDAS qualified timestamps. They are independent, follow the standard and can be checked by anyone.
Sources
- RFC 3161, Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP), IETF, 2001. Sections 2.1, 2.4, 3.4 and 4.
- OpenSSL 3.0 manual, openssl-ts and openssl-verification-options.
- OpenSSL source, crypto/ts/ts_rsp_verify.c, for the checks
ts -verifyperforms. - DigiCert, RFC3161 compliant Time Stamp Authority server.
- Regulation (EU) No 910/2014 (eIDAS), Article 41, and the UK's retained version of Article 41.