A big drawback of end-to-end encrypted messaging services is that, as soon as you lose your device, you lose all your messages. Your private key is gone after all. I was wondering though, wouldn't it be possible to do the following in a chat app for iOS, using certificate pinning and TLS for all communication with the server:
- as soon as a user logs in in the app, an asymmetric keypair is generated and stored locally, and the public key is sent to the database;
- when user X starts a chat with user Y, X's device generates a symmetric encryption key, stores it locally, encrypts it using Y's public key (downloaded from the central database), and sends the cyphertext to the database;
- Y's device, as soon as it comes online, downloads the cyphertext, decrypts it using it's private key, and stores it locally.
Now, X and Y both have the key generated by X's device and can send messages to each other using symmetric encryption, and nobody, except for X and Y of course, has the symmetric encryption key. When, lets say, X gets a new phone, the following will happen:
- X logs in on the new device and sends the new public key to the database.
- Y's device will notice that a new public key was uploaded, downloads this key, encrypts the symmetric encryption key (that it received in step 3) with X’s new public key, and sends the cyphertext to the database.
- X's device downloads the cyphertext, decrypts it using its private key, and can now download all old messages and decrypt them.
So, I guess my question is: what am I missing that makes my design unsafe? Is it just not smart to store keys in the database for a long time, even when they are encrypted with strong asymmetric encryption (lets say like 8192 bits, just for fun)?
Also, I am an iOS developer, and all keys would be stored in the iOS keychain, which is a very safe way of storing information locally. Nothing is 100% secure, I know, but storing stuff there is pretty much the best you can get on iOS as far as I know.