Docs
Overview
There are two public artifacts to know: a certificate and a key. The certificate exists before the unlock minute and is used to encrypt. The key is released at the unlock minute and is used to decrypt.
In practice, you pick an unlock minute and encrypt locally using that minute's certificate. The encrypted file carries enough information to find the right key later. After the unlock minute, anyone with the encrypted file can fetch the released key and decrypt locally.
Your plaintext file never touches timelock.sh. The server only provides certificates before unlock time and keys after unlock time.
Encrypt With OpenSSL
# Set the unlock time and file
UNLOCK=YYYY-MM-DDTHH:MM:00Z
FILE=plaintext.txt
# Download the certificate for this minute.
curl -s https://timelock.sh/api/v1/keys/${UNLOCK}/cert -o cert.pem
openssl cms -encrypt -in ${FILE} \
-recip cert.pem \
-keyopt rsa_padding_mode:oaep -keyopt rsa_oaep_md:sha256 \
-aes-256-gcm \
-outform DER -out ${FILE}.enc
Decrypt With OpenSSL
FILE=plaintext.txt.enc
# Extract the unlock time from the encrypted file.
UNLOCK=$(openssl asn1parse -inform DER -in ${FILE} \
| grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}Z' | head -1)
openssl cms -decrypt -inform DER -in ${FILE} \
-inkey <(curl -fsS https://timelock.sh/api/v1/keys/${UNLOCK}/key) \
-out decrypted.txt
Before the unlock minute, the key endpoint returns
425 Too Early. Once released, a key is public permanently.
API
The API deliberately has one endpoint for the certificate and one endpoint for the key. Both are returned as PEM text.
GET /api/v1/keys/{minute}/cert |
The certificate for encryption. Available up to 30 days ahead. |
GET /api/v1/keys/{minute}/key |
The key for decryption. Returns 425 until the
unlock minute.
|
GET /api/v1/status |
Current certificate horizon and latest released key minute. |
File and Certificate Format
The browser and CLI produce the same OpenSSL-compatible DER CMS
AuthEnvelopedData file.
- Envelope
- CMS/PKCS#7
AuthEnvelopedData, saved as DER. - File encryption
- Fresh AES-256-GCM encryption material is generated locally, then wrapped to the minute certificate with RSA-OAEP/SHA-256.
- Payload
- File bytes are encrypted with AES-256-GCM, so tampering should fail during decrypt.
- Unlock minute
- Stored in the recipient certificate name inside the CMS structure. That is what lets the decrypt page know which released key to fetch.
- Certificate
-
Each minute gets a self-signed X.509 certificate. Its common name is
shaped like
2026-04-15T14:30Z.timelock.sh, its organization istimelock.sh Oracle, and its validity window is the target minute. - Certificate algorithm
- Each certificate contains an RSA-2048 public value used for RSA-OAEP/SHA-256 wrapping.
Trust Model
- Encryption and decryption happen client-side, in your browser or via OpenSSL. Files never touch the server.
- Unreleased keys are encrypted at rest with a backend KEK that only the worker process uses.
- The API server is read-only. It serves certificates and released keys, but cannot release keys early.
- The worker decrypts and publishes due keys on schedule.
- Once a key is released, it is permanent and public. It cannot be retracted.
FAQ
How can I know you won't release keys early?
You can't. This is a trust-based oracle. Use at your own risk. The system is built so the public web app is read-only, but you are still trusting timelock.sh to operate the worker correctly.
What if the service goes down?
Encrypted data stays locked. Do not rely on timelock.sh as your only way to access critical data.
Can I encrypt to a past time?
Yes. The key is already released, so you can encrypt and immediately decrypt.
Full endpoint and error reference: /llms.txt.