All posts
EngineeringSecurity1 July 2026 6 min read

How Reimbilly’s end-to-end encrypted chat works

Team Reimbilly · Engineering

Conversations between a manager and an employee about expenses can touch salaries, health claims, travel plans, and disputes. That’s why chat in Reimbilly is end-to-end encrypted: messages are encrypted on your device before they leave it, and only your conversation partner can decrypt them. Not our servers, not our staff, not a subpoenaed database dump.

The building blocks

We use NaCl “box” encryption (the libsodium/TweetNaCl construction built on Curve25519, XSalsa20, and Poly1305). Every user gets a keypair generated on their own device. The private key never leaves the device — it’s stored in the platform secure enclave (Keychain on iOS, Keystore on Android). Only the public key is uploaded, so others can encrypt messages to you.

Sending a message

  • Your app fetches the recipient’s public key.
  • It generates a fresh random nonce for this one message.
  • NaCl box encrypts the message with your private key + their public key + the nonce.
  • The ciphertext and nonce are stored on the server; the plaintext never leaves your phone.
  • The recipient’s device reverses the process with their private key and your public key.

What our database stores per message: sender id, conversation id, timestamp, a base64 ciphertext blob, and a nonce. What it can reveal about the content: nothing.

Honest limitations

E2E encryption protects message content, not metadata — we necessarily know who talked to whom and when, or the app couldn’t deliver messages. And if you lose every logged-in device, encrypted history is unrecoverable by design; no “support backdoor” exists. We think that trade-off is exactly right for financial conversations.