Skip to content

End-to-End Encryption Architecture ​

zeitkapsl uses end-to-end encryption (E2EE) to ensure your photos remain private and secure. This page explains how the encryption architecture works to protect your data.

Core Concept ​

With zeitkapsl's E2EE architecture, your photos are "locked before they leave your device." Think of it like a photo album with a padlock:

  • Only you and authorized recipients have the key to unlock it
  • The zeitkapsl servers only store the locked album
  • No one else, not even zeitkapsl, can see your photos

What is End-to-End Encryption? ​

End-to-end encryption means that your data is encrypted on your device before being sent to the server, and can only be decrypted by you or people you explicitly share with. The encryption keys never leave your control.

Encryption and keys ​

The Key Hierarchy ​

zeitkapsl uses separate keys for login, account recovery, collections, and media:

Email + password → PBKDF2 + HKDF → encryption key + auth token
Random main key → index key → collection key → media key

The password-derived encryption key wraps the random main key. Each photo or video has its own AES-256-GCM key, and collection keys allow collection sharing without exposing the main key.

Encryption in Action ​

Every photo and video is encrypted with:

  • Algorithm: AES-256-GCM (a strong, standard authenticated cipher)
  • Unique Key: Each media item gets its own random 256-bit key
  • Authenticated Encryption: GCM mode ensures data integrity and authenticity
  • Metadata Protection: Filenames, EXIF data, GPS coordinates, dates, all encrypted

Registration and Key Generation ​

When you create a zeitkapsl account:

  1. Password Entry: You provide your master password (never sent to servers in plain text)

  2. Key Derivation: PBKDF2-SHA512 and HKDF-SHA512 derive an encryption key and an authentication token from your email address and password.

  3. Main Key: Your device generates a random main key. An index key derived from it protects collection keys and search indexes.

  4. Wrapped Main Key: The random main key is encrypted with the password-derived encryption key and stored on the server

    • This allows you to log in from multiple devices
    • The server cannot decrypt this wrapped key without your password
  5. Recovery Kit: A backup of your main key is provided

    • Enables password recovery without server access
    • Critical: Store this safely, because losing it means losing access if you forget your password

Important

zeitkapsl cannot recover your password or decrypt your data. If you lose both your password and recovery kit, your data is unrecoverable. This is a feature, not a bug. It is what makes the encryption genuinely end-to-end.

Sharing Architecture ​

zeitkapsl's sharing system is designed to share access without compromising security.

When you share a collection, zeitkapsl generates a link like:

https://app.zeitkapsl.eu/s/123456789/#abcdef

This link has two parts:

  • Public Part (/s/123456789): Identifies which share on the server
  • Private Part (#abcdef): Contains the secret password, never sent to servers

URL Fragments and Privacy

Per RFC 3986, the fragment (everything after #) is never transmitted to servers. Browsers keep it local, ensuring zeitkapsl servers never see your share passwords.

Sharing step by step ​

  1. You Create a Share:

    • Your device generates a random share password client-side
    • The share password encrypts the album key
    • The encrypted album key is sent to the server
    • The share password is put in the URL fragment (#abcdef)
  2. You Send the Link:

    • The complete link (including #abcdef) is copied to your clipboard
    • You send it to recipients via your preferred method (email, messaging, etc.)
  3. Recipient Opens the Link:

    • Their browser loads the page with the share ID (123456789)
    • JavaScript extracts the share password from the URL fragment (#abcdef)
    • The share password goes through PBKDF2 → HKDF to derive decryption keys
    • The device requests the encrypted album key from the server
    • The device decrypts the album key with the derived key
    • The device uses the album key to decrypt photo keys
    • Photos are downloaded and decrypted entirely client-side
  4. What the Server Sees:

    • A request for share ID 123456789
    • Encrypted album key
    • Encrypted photos being downloaded
    • Never sees the share password or decrypted content

Collaborative Sharing ​

For collaborative albums where recipients can upload:

  1. Recipients receive the album key via the share link
  2. They can encrypt new photos with that album key
  3. The server links uploaded media to the shared collection
  4. All participants see the same encrypted collection

Password Recovery ​

zeitkapsl supports password recovery while maintaining E2EE:

With Recovery Kit ​

  1. You initiate password reset
  2. You provide your recovery kit (contains your encrypted main key)
  3. Your device decrypts the main key locally
  4. You set a new password
  5. The main key is re-encrypted with the new password
  6. The new wrapped main key is sent to the server

No Server Access

The server never sees your main key or new password in plaintext. All decryption and re-encryption happens on your device.

Without Recovery Kit ​

If you lose both your password and recovery kit:

  • Your data cannot be recovered
  • This is by design, no backdoors exist
  • Create a new account and start fresh

Critical: Save Your Recovery Kit

Download and securely store your recovery kit immediately after account creation. Consider:

  • Printing it and storing in a safe place
  • Saving to a password manager
  • Storing in multiple secure locations

What Is Encrypted ​

zeitkapsl encrypts everything sensitive end-to-end:

Data TypeEncryptedNotes
Photos & Videos✅ YesEach file encrypted with unique AES-256-GCM key
Thumbnails✅ YesMultiple sizes, all encrypted
Filenames✅ YesOriginal names encrypted
EXIF Metadata✅ YesCamera info, settings encrypted
GPS Coordinates✅ YesLocation data fully encrypted
Dates & Times⚠️ taken time visible for quota/sorting
Collection Names✅ YesAlbum names encrypted
Collection Descriptions✅ YesAny descriptions encrypted
Search Indexes✅ YesFace data, object labels, OCR text, all encrypted
Folder Structure✅ YesPart of encrypted collection names
Share Passwords✅ YesNever leave your device; stored in URL fragments

What Is NOT Encrypted ​

Some metadata is intentionally not encrypted for functionality and performance:

Data TypeEncryptedWhy Not Encrypted
Upload Size❌ NoRequired for quota tracking
Upload Timestamp❌ NoEnables fast timeline sorting without decryption
Aspect Ratio❌ NoAllows efficient grid layout without decrypting
Account Email❌ NoRequired for login and communication
Billing Information❌ NoRequired for payment processing
Collection Item Count❌ NoEnables fast collection list rendering
Collection Relationships❌ NoWho owns what collection

Design Trade-offs

These choices balance privacy with usability. For example, encrypting aspect ratios would require decrypting every photo just to render the gallery grid, making the app unusably slow.

Technical Implementation ​

Cryptographic Primitives ​

zeitkapsl uses industry-standard, well-audited cryptographic libraries:

  • AES-256-GCM: Symmetric encryption for data
  • PBKDF2-SHA512: Password-based key derivation
  • HKDF-SHA512: Key derivation for sub-keys
  • BCRYPT: Server-side auth token hashing

Key Sizes ​

  • AES Keys: 256 bits
  • Derived Keys: 256 bits

Key derivation ​

A diagram and ASCII reference show the key hierarchy.

Registration, step by step ​

  1. sha512(email) is used as the salt and your password as the key material for PBKDF2, producing the passwordKey.
  2. From passwordKey, HKDF derives an encryptionKey and an authToken.
  3. A mainKey is generated from a secure random source. This is the key your recovery kit backs up.
  4. From mainKey, HKDF derives an indexKey and a passwordResetToken.
    • indexKey decrypts your collectionKey items, which decrypt mediaKey items, which decrypt the actual media blobs and metadata.
    • From indexKey, HKDF derives the searchLabelsKey used for encrypted search.
    • passwordResetToken proves ownership of the mainKey and enables password reset.
  5. The mainKey is wrapped with the encryptionKey using AES-GCM, giving wrappedMainKey.
  6. The authToken is sent to the server and stored hashed with bcrypt. It is effectively your API password.
  7. The server stores wrappedMainKey, your email, and the passwordResetToken.

Key hierarchy:

email + password → PBKDF2 → HKDF → authToken + encryptionKey
mainKey → indexKey + passwordResetToken → collectionKey → mediaKey

Login ​

  1. You enter email and password.
  2. PBKDF2 produces the passwordKey, and HKDF derives the encryptionKey and authToken again.
  3. The client authenticates with authToken and fetches wrappedMainKey.
  4. The client unwraps it with encryptionKey via AES-GCM to recover the mainKey.

Because these keys are recomputed on your device every time, nothing that can decrypt your library is ever stored on our servers.

Recipient decryption flow for a share ​

The secret in a share link (https://app.zeitkapsl.eu/s/123456789/#abcdef) is the part after the #. Per RFC 3986, Section 3.5, the fragment is never sent to the server, so we can deliver the encrypted data without ever learning the key that opens it.

Share password (from #fragment)
  ↓ PBKDF2
Share key
  ↓ HKDF
authKey (bcrypt) + indexKey (AES-256-GCM)
  ↓
Collection key
  ↓
Media keys
  ↓
Files decrypted locally

Recipients decrypt a share with the secret in its URL fragment. zeitkapsl does not receive that fragment.

Open Source Transparency ​

zeitkapsl is open source (GPLv3 licensed):

  • All client-side encryption code is auditable
  • Security researchers can review the implementation
  • Community contributions improve security
  • No security through obscurity

View the source code on Codeberg: codeberg.org/zeitkapsl/zeitkapsl. The cryptography lives in core/pkg/crypto.

And you do not have to read the code yourself to gain confidence: this design was checked by an independent security audit. See independent security audit.

GPLv3 Licensed