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:
- 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.
- 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.
- 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.