Skip to content

Security Improvements

Antonio Calatrava edited this page Sep 24, 2020 · 6 revisions

Thoughts on Security Improvements

Current scenario

Right now the encryption system is based on asymmetric key encryption using RSA 4096. Since this is good for several reasons (highly audited, no public records of being broken, etc.) it has some drawbacks:

  • MITM or Man in the middle attack where a bad actor may be able to intercept our communications and therefore intercept our public/private key pair and generate their own. This way while we think we are encrypting the messages using the public key of the destination address in reality we are using the public key of the bad actor and he is re-encrypting all the messages to the destination.
  • Forward Secrecy: All the encryption relies on the same private key, so if someone is eavesdropping our communications and somehow is able to get our private key it will be able to decrypt all the messages sent from the beginning since all of them are encrypted with the same key.
  • Deniable Encryption: The current system doesn't offer the possibility of plausible deniability, in this case would be the possibility to deny the content of a given message.

Due to the asynchronous type of communication we're dealing with here, there are no easy solutions for any of these problems. However, we'll try to minimize them as much as possible.

MITM Attack

Avoiding a MITM attack is practically impossible. Since we don't have a trustworthy communication channel we can't be completely sure that the public key we get for encryption is real or not. The only way to be sure of it is by using an out-of-band channel to compare the keys.

However, in order to minimize this problem, we could not trust only one keyserver but at least 2 of them. So when asking for the public key of our destination address we need to ask at least 2 different keyserver nodes and trust the key if it's the same in both of them. If it's not the same we should query another keyserver and expect at least 2 of them to have the same key.

This could minimize the problem if one keyserver has been compromised but it will not fix the problem if our network link is compromised. So, in addition, we should add a way to compare the key side by side in a meeting or by phone call.

Forward Secrecy

"In cryptography, forward secrecy (FS), also known as perfect forward secrecy (PFS), is a feature of specific key agreement protocols that gives assurances that session keys will not be compromised even if long-term secrets used in the session key exchange are compromised."

As explained above, using the same key to encrypt all the messages is not good. If the private key gets leaked or obtained all our past, present and future communications will be exposed.

In order to fix this problem and achieve forward secrecy, every message needs to be encrypted using a different temporary key. Also this keys needs to be forgotten once the message is decrypted. On IM applications it's relatively easy to do that since both parties of the communication are connected, so they can exchange a session key in realtime for that communication or even for every single message. However in our system, the communication is asynchronous so we need to figure out a way to achieve forward secrecy when only one party is trying to communicate with the other.

Signed PreKeys

We can generate a bunch of prekeys signed with our private key (similar to what Signal does) and send them to our keyserver. So the system will work like this:

alice! wants to send a message to bob!

alice! asks to bob!'s keyserver for a prekey

alice! verify that prekey signature with the master public key of bob!

alice! encrypts the message with the prekey and sign the message with her master private key

alice! sends the message

In some systems (like Signal) the prekey is only used once, however, in order to keep it simple, we could have a prekey per day. So we will generate and send, for instance, 7 prekeys to the keyserver for the next week, and every prekey is valid for each day. So if the prekey is leaked only the messages of "today" can be decrypted.

What is a Signed PreKey?

A prekey is a key generated beforehand to establish encrypted communication. It could be half of an ECDH key exchange, or it could be a public/private RSA key pair as well. In order to authenticate that the key comes from the intended destination, it should be signed with the destination master private key.

Problems that need solution for this system to work

  1. Multiple clients problem: When using signed prekeys some client in possession with the master key needs to generate and send those prekeys to the keyserver. However we could have several clients to access our messages. So either we need a form of syncing our prekeys between our clients or we could generate the prekeys deterministically so all the clients will generate the same ones. In fact it would be good to generate deterministically the master key and the prekeys by generating a seed that we can keep safe to setup new clients based on that seed.

  2. Messages in the server: Encrypting messages with different keys will have the problem that we will be unable to decrypt the server messages if we remove those prekeys. So we need to think if we should keep all the prekeys stored on the client vault permanently or not... Now that I think of it if we generate the keys deterministically there is no need to store the keys since we can regenerate them based on the seed and the time... So we could access all the messages in the server at any point in time. Sweet!

Deniable Encryption

This one is tricky. In this context may not be possible to deny having received a message since there could be some traces left on the mailserver that could expose it. In order to do that there should be a system where a different content would be revealed if you are forced to give your keys.

...to be continued

Clone this wiki locally