I want to build a group chat app where messages are transmitted and stored as securely as they can be, but where the message history is still visible after you or others in the group have changed devices. From my understanding, PFS isn't possible here.

It seems that WhatsApp has implemented PFS, which makes sense because its experience is such that, if you change devices, the previous history is gone/not decryptable. But, after researching Messenger and Discord, seems that they store everything in cleartext? Messenger has a "secret messages" mode, which appears to use PFS, however.

Anyway, my first thought here is to have two public/private key pairs for the user (account, and device), and one symmetric key for the group to decrypt messages. For the sake of simplicity, this example assumes that a user can only be in one group chat. My thought is that it would work this way:

  1. A user has a public/private key pair generated when they sign up (we will refer to this as the account encryption key pair). This will be used for direct user-to-user messaging where history needs to be kept.
  2. When a user logs into a device, they generate a public/private key pair for the device. The public key from this pair is sent to the server. The server then sends the user the account key pair and the group chat's symmetric key, and both are encrypted with the device's public key.
  3. If the user changes devices, a new device key pair is generated.

This obviously adds a level of safety, but I'm still uncomfortable with this approach, because nothing prevents someone from getting around the server permissions (though there will be IAM) and grabbing all these keys. I also am not sure the best way to store the group chats' symmetric keys.

Another constraint is that I may not be able to store duplicate messages that are encrypted with everyone's public keys because of storage costs. Please also assume that a key management service like Keysafe or KMS is available, though they obviously come with limits.

What do you guys think? Am I being stupid? I looked at some other similar posts, but saw answers that didn't include tangible solutions.

1 Answer 1


As long as you're keeping the private keys in a server there will always be a risk for someone to access the messages content, either external or internal.

The only way around that would be for the private keys to never touch the server.

I'm currently working on a messaging app that has that history constraint while also wanting for the server to be unable to open any message. Currently we're exploring the use of BIP39 (Bitcoin Mnemonic Code) for the generation of the root keys, from which we then derive sub-keys for each chat room. It's a pain for the UX, since the users will have to store their mnemonic code somewhere and input it again when they login in a new device, but it's the only solution we found that guarantees zero knowledge in the backend. And from what I can gather, I don't think there's any easy solution for this problem.

The approach you've written certainly seems to be valid but I wonder if the added complexity is translated into added security (the private keys are also stored in the server).

EDIT: Take into consideration that I'm not a security expert.

  • Private keys can be stored on the server if they're encrypted, then it's just a matter of having some way for the clients to decrypt the keys when they take them off the server (passphrase/keyfile/etc.).
    – user
    Oct 29, 2020 at 17:31
  • @user Well pointed. In our case we don't want to do that because the users tend to choose weak passwords and there might be confusion to if it's the account password or keys password. But it's definitely something to consider.
    – lm2s
    Oct 30, 2020 at 8:56
  • If you use Argon2 with a very large difficulty to derive the key from the user's password, it should not matter. It does not matter for the client if the key derivation takes 2 minutes when he installs the app on a new device, and you can use the account password for that.
    – ThoriumBR
    Mar 18, 2023 at 23:46
  • And if someone steals the encrypted private keys, 2 minutes per account per password trial will be insanely expensive to crack.
    – ThoriumBR
    Mar 18, 2023 at 23:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .