RFC 3161 timestamp · technical guide

What an RFC 3161 timestamp is and how to verify it

A time-stamping authority (TSA) signs a file’s fingerprint together with a date and a time. Here is what that response contains, how to check it with OpenSSL or in the browser, and how to request one through an API.

Looking to convert a Unix timestamp to a date? This is something else: here a date is put on a file.

Verify a .tsr

Opens the validator: you add the file and its timestamp, and the fingerprint is computed in your browser.

Issue them from your own system: the API →
Only the fingerprint travels The request carries a SHA-256: the authority never sees the file.
Open standard RFC 3161, the IETF protocol time-stamping authorities have used since 2001.
Verified without anyone With OpenSSL or any validator, without relying on whoever issued it.

What it is

A request, an authority and a token.

RFC 3161 is the standard for time-stamping, and what it does is simpler than it sounds.

The request carries the fingerprint

The client computes the file’s SHA-256 and sends the authority only that fingerprint, with a random number (nonce) to recognise the response. The file does not travel.

The TSA signs the time

The time-stamping authority binds that fingerprint to a date and time from its clock, and signs it with a certificate authorised for time-stamping only.

The response is the token

It returns a .tsr: the status of the request and, if granted, the signed token. With the file and the token, anyone can check it later.

Inside the .tsr

What is inside a .tsr.

A .tsr is an ASN.1 structure encoded in DER. These are the fields that matter, under the names the standard gives them.

status
The status of the request: granted or rejection, among others. It sits in front of the token, and it is what trips validators that only expect a .tst.
messageImprint
The algorithm (SHA-256) and the file’s fingerprint. This is what gets compared with the file you hold.
genTime
The date and time the authority signs, in UTC. This is the time of the timestamp.
serialNumber
The number the authority assigns to that token, unique among all the tokens it issues.
policy
The identifier (OID) of the time-stamping policy it was issued under.
nonce
The request’s random number, returned as is: it shows that this response belongs to that request.
SignedData
The CMS envelope: the authority’s signature over all of the above and, if the request asked for it, its certificate. Sellat always asks for it.

A .tst is the token alone, without the status. Both carry the same proof: the envelope changes, not what it proves.

Qualified or not

The same token, two legal levels.

Technically, an RFC 3161 token is the same whoever issues it: the fingerprint, the time and the signature are checked the same way. What changes is who signs it.

Regulation (EU) 910/2014 (eIDAS) calls a timestamp qualified when it meets its article 42: it binds the date and time to the data so as to reasonably preclude the data being changed undetectably, it is based on an accurate time source linked to Coordinated Universal Time, and it is signed or sealed by a qualified trust service provider, listed as such on a Member State’s trusted list.

No electronic timestamp may be denied legal effect or admissibility as evidence solely because it is electronic or not qualified (art. 41.1). A qualified one also enjoys the presumption of the accuracy of the date and time and of the integrity of the data (art. 41.2).

How to get a qualified timestamp issued by the FNMT-RCM →

Verify with OpenSSL

Three commands, on your own computer.

You need the file, the .tsr and the certificate of the authority that signed it (in a Sellat package, autoridad-sellado.pem). Nothing leaves your machine.

  1. 01

    Read what the timestamp says

    openssl ts -reply -in timestamp.tsr -text

    Shows the status and the token’s contents: the policy, the fingerprint (“Message data”), the serial number, the time and the nonce.

  2. 02

    Compute the file’s fingerprint

    openssl dgst -sha256 file

    It must match the “Message data” from the previous step, which OpenSSL prints in hexadecimal blocks. Change a single byte of the file and it no longer matches.

  3. 03

    Verify signature and fingerprint together

    openssl ts -verify -in timestamp.tsr -data file -CAfile autoridad-sellado.pem -partial_chain

    If everything holds, it answers “Verification: OK”.

The authority’s certificate is a leaf, not a CA: without -partial_chain OpenSSL looks for its issuer and fails. It is the most common reason a validator rejects a correct timestamp. If what you have is a .tst, add -token_in to the commands.

Verify in the browser

The timestamp validator accepts the .tsr or the .tst together with the file. The fingerprint is computed on your device and only the fingerprint and the timestamp are sent. It tells you separately whether the structure, the fingerprint, the signature, the signing certificate and the EU trusted list hold.

Verify a .tsr

Through the API

How to get one through Sellat’s API.

Sellat is not a time-stamping authority: the RFC 3161 token you get through Sellat is the qualified timestamp issued by the FNMT-RCM. Sellat requests it over the fingerprint you send, verifies it against the EU trusted list and keeps it inside your proof.

  1. 01

    Compute the fingerprint

    The file’s SHA-256, on your own system. It is the only thing sent.

  2. 02

    Create the proof with the timestamp

    POST /api/v2/proofs with "qualified": true, or POST /api/v2/proofs/{id}/qualified on a proof that already exists. With an Idempotency-Key, a retry never counts twice or seals twice.

  3. 03

    Download the .tsr

    GET /api/v2/proofs/{id}/qualified.tsr returns the authority’s response as is, in DER, ready for OpenSSL.

curl https://sellat.app/api/v2/proofs \
  -H "Authorization: Bearer $SELLAT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hash":"<the file's sha256>","qualified":true}'

Each one uses up a timestamp from your account: the welcome one or one from your packs. With none left, the API answers 402 before creating anything.

Scope

What it proves, and what it does not.

What it proves

A valid RFC 3161 token proves that this fingerprint, and so this exact file, existed no later than the time the authority signed, and that it has not changed since.

What it does not prove

It fixes since when the file exists, not since when what its content shows exists. It does not prove authorship, ownership or truthfulness; and the time is worth what the authority that signs it is worth.

Frequently asked questions

Before you ask.

Are timestamp, time stamp and time-stamping the same thing?

Yes: they are one concept under several names. The European regulation calls it an “electronic time stamp”. What changes between one and another is not the name but whether they are qualified.

What is the difference between a .tsr and a .tst?

The .tsr is the authority’s complete response (TimeStampResp): the request status plus the token. The .tst is the token alone (TimeStampToken, a CMS SignedData). Many validators only accept the .tst; with OpenSSL, a .tst is read by adding -token_in.

Why does OpenSSL say it cannot find the certificate’s issuer?

Because the authority certificate you pass with -CAfile is a leaf, not a CA, and OpenSSL tries to build the chain up to a root. With -partial_chain it accepts the leaf as a trust anchor and verifies the timestamp.

Is a free TSA good enough?

To prove technically that a file existed, yes: an RFC 3161 token is an RFC 3161 token. What you do not get is the legal presumption of article 41.2, which only comes with a timestamp issued by a qualified provider on the EU trusted list.

Which time is the one that counts?

In the timestamp, the genTime field, which the authority signs in UTC. A Sellat proof also carries the time of the public anchor: they are different times, from different layers, and are always shown separately.

Can I verify a .tsr that is not from Sellat?

Yes. OpenSSL and this site’s validator accept a .tsr or .tst from any authority. The validator only calls it qualified if the authority appears as a qualified service on the EU trusted list.

Can I automate it?

Yes. The API accepts fingerprints over HTTP and returns one proof for each, without sending the originals; there is also an open-source command-line tool. It is what we use ourselves to timestamp logs every hour.

Holding a .tsr right now?

Check it in the browser with its file. If what you want is to issue them from your own system, start with the API.

Open the validator Issue them from your own system: the API →