Skip to content

Timestamp Authority

By Romi Fadli, S.Kom. 9 min read Security & Secrets
On this page
A document's fingerprint passing through a clock, signed by a certificate below it, and returning as a time seal stamped on the same document

Timestamp Authority adalah service Rust yang menjawab satu request dengan satu pernyataan bertanda tangan: sidik jari persis dari dokumen ini sudah ada pada detik ini. Ia mengimplementasikan time-stamping RFC 3161 untuk PDF bertanda tangan, dan sekaligus menjadi certificate authority kecil bagi dirinya sendiri — ia menerbitkan, menyimpan, dan memperbarui sertifikat yang dipakainya untuk menandatangani, menerbitkan informasi pencabutan untuk sertifikat itu, dan mencatat setiap token yang pernah dihasilkannya.

Saya membangunnya karena tanda tangan digital hanya membuktikan siapa yang menandatangani, bukan kapan. Sertifikat penanda tangan kedaluwarsa setelah beberapa tahun dan bisa dicabut besok, dan tanpa bukti terpercaya tentang waktu penandatanganan, pembaca tak bisa tahu apakah tanda tangan dibuat selagi sertifikatnya masih baik. Stempel waktu dari otoritas yang independen, tertanam di dalam PDF, adalah bukti itu, dan ia menjaga tanda tangan tetap bisa diverifikasi lama setelah sertifikat di belakangnya habis.

Sekilas

Bahasa & frameworkRust, dengan actix-web, sqlx di atas PostgreSQL, dan mesin time-stamping OpenSSL lewat interface C-nya
ArsitekturFlat Layered
Versi2.11.2
StatusStabil, berjalan di production
BentukService HTTP mandiri: endpoint time-stamping dan pencabutan yang publik, serta API terautentikasi untuk administrasi
Kode sumberPrivat
Apa module ini dan bagaimana keadaannya.

Yang dikerjakannya

A. Membubuhkan waktu pada sidik jari dokumen

Aplikasi penanda tangan mengirim time-stamp request yang hanya membawa hash dokumen, tak pernah dokumennya. Service menjawab dengan token bertanda tangan yang mengikat hash itu dengan waktu saat ini, nomor serial yang unik, dan nonce client, lalu aplikasi menanamkan token itu di PDF di samping tanda tangannya.

B. Menerbitkan dan memperbarui sertifikat penanda tangannya sendiri

Sertifikat yang menandatangani setiap token dibuat oleh service itu sendiri, di bawah intermediate CA miliknya, pada start pertama. Ketika masa berlakunya hampir habis, request berikutnya memperbaruinya sebelum menandatangani. Service tak pernah menstempel dengan sertifikat kedaluwarsa, dan tak ada orang yang harus ingat menggantinya.

C. Membiarkan siapa pun memeriksa sertifikatnya

Validator yang membaca stempel waktu bertahun-tahun kemudian harus bisa memercayai sertifikat yang menandatanganinya. Service menerbitkan sertifikat intermediate CA-nya, certificate revocation list, dan OCSP responder, semuanya tanpa autentikasi, di alamat yang tertulis di sertifikatnya.

D. Menyimpan catatan setiap token

Setiap respons disimpan beserta waktunya, policy, algoritma hash, sidik jari dokumen, nonce, dan nomor serial sertifikat penanda tangannya. Token mana pun yang pernah diterbitkan service bisa ditelusuri kembali ke request yang menghasilkannya.

E. Mengatur administrasi

Time-stamping dan pemeriksaan pencabutan bersifat publik; mencabut sertifikat serta mengelola user, role, dan access token mewajibkan token bertanda tangan dengan role yang sesuai.

Antarmuka

KemampuanAkses
Menstempel waktu satu hash: request RFC 3161 masuk, respons bertanda tangan keluarpublik
Sertifikat intermediate CA dalam DER, di alamat yang ditunjuk sertifikatpublik
Certificate revocation listpublik
OCSP, lewat GET dan POSTpublik
Readiness, mencakup database dan root CApublik
Mencabut sertifikat dengan alasan RFC 5280token
Login; mengelola user, role, password, dan access tokentoken, menurut role
Yang dibuka service, dan siapa yang boleh memakainya.

Client RFC 3161 mana pun bisa memakainya. Begini perjalanan pulang-pergi dengan OpenSSL, terhadap host contoh:

bash
openssl ts -query -data contract.pdf -sha256 -cert -out request.tsq
curl -s -H 'Content-Type: application/timestamp-query' \
  --data-binary @request.tsq http://tsa.example.org/ -o response.tsr
openssl ts -reply -in response.tsr -text

Standar

StandarYang dijaminnya di sini
RFC 3161, Time-Stamp Protocolrequest dan token yang sudah dipahami penanda tangan dan validator PDF
CMS SignedData (RFC 5652)token yang ditandatangani dalam format amplop yang sama dengan tanda tangan yang dilindunginya
X.509 v3 dan RFC 5280sertifikat penanda tangan yang dibatasi untuk time-stamping, dan daftar pencabutan yang bisa dibaca validator mana pun
RFC 6960, OCSPjawaban pencabutan untuk sertifikat penanda tangan, lewat GET atau POST
Authority Information Access dan CRL Distribution Pointssertifikat yang memberi tahu validator di mana issuer dan status pencabutannya bisa ditemukan
JSON Web Token dengan RS256access token untuk administrasi, ditandatangani key yang bisa dirotasi service
W3C Trace Context dan OpenTelemetrytrace, log, dan metrics yang menyambung trace pemanggil
Standar yang dipatuhi service, dan yang dijamin masing-masing.

Di dalamnya

Service ini mengikuti bentuk Flat Layered yang sama dengan certificate authority tempat ia bercabang: route, controller, service, repository, dan helper berjajar satu tingkat, dengan satu file per operasi — menjawab time-stamp request, membuat sertifikat penanda tangan, menjawab OCSP, membangun daftar pencabutan. Keduanya berbagi kode sampai titik percabangan; mesin time-stamping, siklus hidup penanda tangan, dan catatan token dibangun sesudahnya, dan perbaikan yang dibuat belakangan di salah satunya sengaja dibawa ke yang lain.

Keputusan rancangan

Kriptografinya milik OpenSSL; yang milik saya hanya keputusannya. Time-stamping punya banyak field yang harus tepat persis, dan OpenSSL sudah punya mesin time-stamp response yang menghasilkannya. Jadi saya menjalankan mesin itu lewat binding yang dibuat hanya untuk daftar fungsi yang sempit, tidak menyusun strukturnya dengan tangan. Dua nilai tak diserahkan ke OpenSSL. Nomor serial tiap token berasal dari sequence database tersendiri, terpisah dari nomor serial sertifikat, dan diberikan ke mesin lewat callback. Waktu dibaca sekali per request dari jam host, yang dijaga sinkron dengan NTP, dan diberikan dengan cara yang sama, sehingga waktu di token dan waktu di catatan adalah detik yang sama.

Token harus bisa dibaca tool yang akan memeriksanya. Pada versi pertama, library Python penanda tangan PDF yang banyak dipakai menerima respons yang berisi status tapi tanpa token di dalamnya. Penyebabnya ada pada cara request sampai ke OpenSSL — mesin diberi request asli, bukan request yang sudah disesuaikan — dan perbaikannya mengubah empat bagian sekaligus: request di-encode ulang sebelum diteruskan, sertifikat penanda tangan selalu disertakan di respons — juga bila request tak memintanya — digest yang dipakai sesuai panjang sidik jari kiriman client, dan respons yang tak akan membawa token langsung gagal, tak dikembalikan seolah-olah jawaban.

Rantai berhenti di bawah root. Tiap token membawa sertifikat penanda tangan dan intermediate CA, supaya validator bisa menyusun jalurnya, tapi tidak root: root adalah trust anchor yang harus sudah dipegang validator, dan menyertakannya hanya membuat setiap token lebih besar. Satu versi awal pernah menyertakannya; saya mencabutnya lagi.

Sertifikat penanda tangan dibuat di dalam, tak pernah diminta dari luar. Satu-satunya sertifikat yang dipakai service ini untuk menandatangani token adalah sertifikat yang dibuatnya sendiri. Profilnya dikunci di kode, bukan di konfigurasi — bukan CA, key usage critical dan terbatas pada digital signature dan non-repudiation, extended key usage critical dan terbatas pada time-stamping — karena dua insiden menunjukkan akibat profil yang dibiarkan longgar: satu sertifikat terbit tanpa tujuan time-stamping, dan satu angkatan awal terbit sebagai versi 1 padahal membawa ekstensi versi 3. Service membuat sertifikat itu pada start pertama, menolak start bila gagal, dan memperbaruinya di dalam jalur request sebelum masa berlakunya sempat habis.

Setiap token meninggalkan bukti, dan bukti itu tak menyimpan dokumen. Service tak pernah menerima dokumen, hanya hash-nya, jadi ia bisa mencatat dan menyimpan sidik jari secara utuh tanpa memegang apa pun yang rahasia. Tiap respons disimpan bersama waktu, policy, algoritma, sidik jari, nonce, sertifikat penanda tangan, dan request id, dan tiap request memancarkan atribut telemetry untuk non-repudiation — siapa yang meminta, dari mana, dan apa yang distempel — dengan rantai mentah alamat forwarding disimpan hanya sebagai bukti. Respons dikirim dengan no-store, karena stempel waktu yang di-cache adalah stempel waktu yang salah.

Pencabutan sertifikat penanda tangan bekerja sama seperti di certificate authority. OCSP responder punya signer sendiri, memantulkan nonce, menyertakan intermediate CA, dan sedikit memundurkan awal tiap jawaban untuk client yang jamnya terlambat; daftar pencabutan berversi 2, dibangun lewat interface C OpenSSL. Alamat di setiap sertifikat memakai HTTP biasa, karena memeriksa pencabutan lewat TLS berarti lebih dulu memeriksa sertifikat TLS-nya, dan sertifikat responder menunjuk issuer-nya, tak pernah dirinya sendiri.

Kepercayaan berawal dari root, dan operasinya mengikuti pelajaran certificate authority. Intermediate CA diverifikasi terhadap root setiap kali start. Administrasi memakai token bertanda tangan dengan key identifier dan id token yang bisa dicabut; telemetry lewat OpenTelemetry dengan metrics delta; readiness mewajibkan database dan root CA sekaligus; dan migration ikut di dalam image, karena menjalankannya hanya pada database kosong pernah membuat perubahan skema berikutnya tak sampai ke staging maupun production.

Spesifikasi

MasukanTime-stamp request RFC 3161 yang membawa hash dokumen dan nonce opsional; pertanyaan OCSP dan unduhan daftar dari validator mana pun
HasilTime-stamp response bertanda tangan, jawaban OCSP, daftar pencabutan versi 2, dan sertifikat intermediate CA
WaktuJam host yang disinkronkan NTP, dibaca sekali per request; akurasi satu detik
KeyRSA 4096 untuk sertifikat penanda tangan dan responder
PenyimpananPostgreSQL, memegang setiap token dan sertifikat yang diterbitkan, dengan migration yang dikirim di dalam image
Diverifikasi denganTool time-stamp milik OpenSSL dan library penanda tangan PDF yang menanamkan tokennya
Berjalan sebagaiImage container, sebagai user non-root, dengan konfigurasi di-mount dari volume
Yang diterima, dikembalikan, dan dibutuhkan service.

Terkait

Certificate authority tempat service ini bercabang, yang berbagi desain pencabutan dan aksesnya.

Toolkit yang menjalankan migration service ini saat satu rilis sampai ke production.

Ke mana atribut audit, trace, dan metrics service ini pergi setelah meninggalkannya.

Istilah

Timestamp authority
Service terpercaya yang menandatangani pernyataan bahwa data tertentu sudah ada pada waktu tertentu.
Message imprint
Hash dokumen yang dibawa time-stamp request sebagai pengganti dokumennya.
Nonce
Angka acak yang ditaruh client di request dan diharapkan kembali di jawaban, supaya jawaban lama tak bisa diputar ulang.
Intermediate CA
Certificate authority yang sertifikatnya ditandatangani root, dan yang menandatangani sertifikat yang melakukan pekerjaan sebenarnya.
OCSP
Online Certificate Status Protocol: client menanyakan apakah satu sertifikat masih sah dan menerima jawaban bertanda tangan.
Trust anchor
Sertifikat root yang sudah dipercaya validator, tempat setiap rantai yang diperiksanya harus berakhir.

Technologies covered

  • Rust
  • PostgreSQL
  • OpenTelemetry
  • OCSP
  • X.509

About the author

Photo of Romi Fadli

Romi Fadli, S.Kom.

Solution Architect · Backend Engineer · Embedded Systems

In my day job I work as a solution architect. I design the system, lead the team that builds it — quality assurance, backend developers, a UI developer, DevOps and DevSecOps — and write the most critical modules myself, such as a certificate authority, a long-term PDF signer, and the core API of a personnel system.

I work across the whole stack that a running system actually needs. On the hardware side that means PCB design, microcontrollers, and embedded firmware — including RISC-V boards running FreeRTOS and Embassy, speaking MQTT over mutually authenticated TLS on a microcontroller with 64 KB of SRAM.

Most of my day-to-day work is software: Rust backends and API modules built on Clean Architecture, an OAuth2/OpenID Connect authorization server written from scratch, PAdES document signing, and certificate authorities — root CAs, timestamping authorities, and OCSP responders. I also build the frontends that sit on top of them.

Running all of that means infrastructure: Docker Compose stacks, networking, Mikrotik and RADIUS, observability with OpenTelemetry, and a steady habit of writing command-line tools and utilities for Linux when the existing ones do not fit.

Share

Enjoyed this?

Get an email when a new article is published.

Referenced by

A central core holding people, organisations, documents, and certificates, connected to eight surrounding services for storage, addresses, certificates, timestamps, the root, signing, thumbnails, and face challenges

Inti Laravel dari platform penandatanganan dokumen: memegang user, identitas, organisasi, sistem client, dokumen beserta versi bertanda tangannya, stempel, dan sertifikat, serta mengorkestrasi service yang menandatangani, menstempel waktu, merender, dan menyimpan — tanpa pernah memegang file.

9 min read Read more →
A locked offline host holding the root key, a signed revocation list crossing an air gap to a small publisher server, which serves the root certificate and the list to a validator

Service kecil yang hanya menerbitkan, menjaga root CA tetap bisa dijangkau tanpa bisa disentuh: ia menyajikan sertifikat root dan daftar pencabutannya, sementara key root dan setiap tanda tangan tetap di host offline — bisa dipakai project mana pun yang punya CA sendiri.

7 min read Read more →
A signed PDF with a QR stamp, wrapped in four nested frames for the signature, its timestamp, the embedded validation data, and the archive timestamp

Service Python yang menandatangani PDF sampai PAdES B-LTA dengan stempel yang terlihat — menanamkan stempel waktu, sertifikat, dan bukti pencabutan, lalu stempel waktu arsip — supaya tanda tangan tetap bisa diverifikasi lama setelah sertifikatnya kedaluwarsa, dan memverifikasi PDF bertanda tangan.

10 min read Read more →
A purple root circle linked to a blue and an orange intermediate circle, which lead to a signed document with a green seal and to a clock.

Aurograf

DevOps

Platform tanda tangan digital Pemerintah Kota Tangerang Selatan: penanda tangan membuktikan identitasnya, menandatangani PDF hingga PAdES B-LTA dengan sertifikat dari otoritas milik platform sendiri, dan siapa pun bisa memverifikasinya — versi 2, yang saya rancang, bangun, dan operasikan.

10 min read Read more →

Related Articles

A memory chip holding a key, circled by refresh arrows, beside a browser window where a signature stamp is being dragged into place on a PDF page

Aplikasi browser Vue dari platform penandatanganan dokumen: sesi disimpan di memori dan diperbarui oleh satu refresh berantrean, login PKCE, stempel ditaruh presisi di halaman PDF, verifikasi identitas dengan tantangan wajah, persetujuan client, dan administrasi berbasis role.

10 min read Read more →
A central core holding people, organisations, documents, and certificates, connected to eight surrounding services for storage, addresses, certificates, timestamps, the root, signing, thumbnails, and face challenges

Inti Laravel dari platform penandatanganan dokumen: memegang user, identitas, organisasi, sistem client, dokumen beserta versi bertanda tangannya, stempel, dan sertifikat, serta mengorkestrasi service yang menandatangani, menstempel waktu, merender, dan menyimpan — tanpa pernah memegang file.

9 min read Read more →
A signed PDF with a QR stamp, wrapped in four nested frames for the signature, its timestamp, the embedded validation data, and the archive timestamp

Service Python yang menandatangani PDF sampai PAdES B-LTA dengan stempel yang terlihat — menanamkan stempel waktu, sertifikat, dan bukti pencabutan, lalu stempel waktu arsip — supaya tanda tangan tetap bisa diverifikasi lama setelah sertifikatnya kedaluwarsa, dan memverifikasi PDF bertanda tangan.

10 min read Read more →