Not every project is cut out in a way that it simply takes in our chat app samples for iOS, Android or JavaScript. This guide walks you through the steps of implementing end-to-end encryption DIY!

Architectural overview of end-to-end encryption

E2ee is predominantly client-heavy: most key creation, encrypt and decrypt functions happen on the client devices to keep clear data and keys out of the cloud. However, your project will still need to run some minimal backend code to operate.


What your backend code does, is: generate Virgil JWT tokens to your Firebase-authenticated users. Otherwise, all users on the internet will be able to access your Virgil account's APIs, which we want to avoid.

Running backend code in Firebase

We implemented the backend code using Node.js, running as a Firebase Function.'/generate_jwt', (req: IRequestWithFirebaseUser, res: express.Response) => {
  if (!req.body || !req.body.identity) res.status(400).send('identity param is required');
  const virgilJwtToken = generator.generateToken(req.body.identity);
  res.json({ token: virgilJwtToken.toString() });

See the Function's TypeScript code on GitHub. To keep things easy for you, let's deploy this pre-created function for your app: follow the deployment instructions here.

Client app/frontend

Once you have your Firebase user authentication working and the Virgil Function published, your client app is ready to connect to Virgil's key management infrastructure & APIs. You're now ready to build things!

Install & Init Virgil SDK

Follow this guide to learn how to install & init the Virgil SDK in your app. Skip the server side installation steps: we already covered your backend code as part of publishing your Firebase function.

User private + public keys

In an end-to-end encrypted app, every user needs to have their own private and a public keys:

  • Public key: user public keys are published on Virgil's Cards cloud Service. Users can download each other's public keys and encrypt data with them to each other. "Virgil Card" means: a user's public key + metadata (e.g. email address) to make it searchable for other users via Virgil's Cards Service.
  • Private key: a user's private key decrypts the data that was encrypted using her public key. We keep the private keys on the devices and back them up to the cloud, encrypted with the users' passwords - we'll get back to this later.

In your signup function, generate a private key for every user at signup time. Generate the user's public key from the private key and publish it to Virgil's Cards Service, so that other users can find it and encrypt messages to her. If you already have users, generate their keys the next time they log in.

Follow this guide to learn how to modify your user signup (and login) functions to generate private keys for your users and publish their public keys to Virgil's Cards Service.

Load user private key at login time. Encrypt messages

Follow this guide to learn how to load user private keys at login, sign & encrypt a message from one user to another

How to decrypt messages

Follow this guide to learn how to decrypt & verify the integrity of a message

How to save and recover the user's private key

Your users will lose their phones and with it, their private keys. Follow this (unpublished, draft) article to implement a password-based key recovery using BrainKeys.

Related howtos:

Did this answer your question?