2

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.

0

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.

| improve this answer | |
  • 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 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 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.