I just had a discussion with (the inimitable) Trevor Perrin about the following promising idea, which could grant us sender ID anonymization and also some forward secrecy:
When encrypting a file, we encrypt fileKey using our persistent key pair. But then, the header is encrypted using a new, one-time use ephemeral key pair, and the public key for that ephemeral key pair is the one we send in the clear. Once the header is decrypted using the ephemeral key pair, we decrypt the underlying fileKey using the now-decrypted persistent sender ID located inside the header.
I love this and I want to implement it as soon as possible. This two-week review period is producing amazing feedback.
I'm confused on this flow. If you encrypt the fileKey with your own key pair, how can the other party decrypt it? Don't you need to encrypt the fileKey with their public key?
Also, if only the public key of the ephemeral key pair is sent with the encrypted file, how will the other party decrypt the header? How do they know the secret key of the ephemeral key pair?
Would it be possible to clarify in an Alice/Bob use case?
With immense thanks to Trevor Perrin
@diafygi Check the updated spec in the above commit.
Got it, thanks! So this is accomplishes half of what Perfect Forward Secrecy aims to do, which is prevent later decryption of a message when either of the sender or receiver's secret keys is compromised. .n this implementation, the sender cannot later decrypt the message since they forget the ephemeral key.
However, if the receiver's key later gets compromised, the message can be decrypted. Unfortunately, we would need the receiver to first send an ephemeral key to obtain perfect forward secrecy, so I doubt PFS would be implemented in miniLock.
One concern I have: the sender can choose the option to include themselves in the recipient list. If they do this, it pretty much blows away the forward secrecy benefit since a later compromise of their key will allow decryption of the message. I know that the primary intention of this feature is to anonymize the sender to the passive collector, so I don't think this is a fundamental flaw.
Hiding the sender ID is a good thing.
But I fail to see how this patch would provide pfs. As far as I understand the changes, the metadata is encrypted twice. Both times to the recipients publickey.
The inner box is signed by the senders key, the outer box (which also contains the sender keyid header in the plain) with the ephemeral key. So what it effectively achieves is to encrypt the senders keyid header in a box with an ephemeral key signature.
@aiafygi even in the old design the sender was not able to decrypt (except if he included himself in the recipients list), since he forgot the fileKey, nothing changed there. or not?
@o- in the old design the senderID is in plaintext, so a passive collector could index messages by senderID. Then when they later compromised the sender's private key, they could just lookup all the past messages send by that user and see if any of them could be decrypted (i.e. sender includes themselves as a recipient). This new implementation prevents this fast lookup from being effective.
@diafygi right it makes correlation harder, but does not prevent decryption of old messages after key material was compromised...
Another concern i have: The outer box is basically unauthenticated (the signature is from a ephemeral key). In the old design the sender keyid presented in the ui was guaranteed to authenticate the whole header block.
upd: what I'm trying to say is: you have no way of validating the inner packets, which are properly signed, before subjecting yourself to a potential decryption oracle situation while decrypting the outer packet.
The difficulty with forward secrecy in the minilock context is that receiver can't advertise a new randomly generated public key in addition to the long term receiver public key. Thus the secret key used to receive the message will always be deterministically related to reciever's passphrase.
@stefanperson TOTP works by deriving a current key from a previously shared key + current time. If you are sending something to a user for the first time. How do know get the previously shared key?
I don't understand how this has something to do with forward secrecy. I'm really confused, and some more explanation would be helpful. I do understand how it provides sender anonymity to everyone except the intended recipients.
Supposing the sender isn't one of the actual recipients, then shouldn't they (or someone who steals their private key) already be unable to decrypt the minilock file they just created, because the file keys are only decryptable by knowing the recipient's private key?
With PGP, if someone steals your private key, they can sign things as you, and decrypt everything that was encrypted to you, but they can't decrypt anything you encrypted to someone else, unless you added yourself as a recipient (I think PGP actually does that by default). How is miniLock compared to that?
@defuse I agree that just saying "forward secrecy" is too strong. The claim was meant to address the extra protection given by using ephemeral keys as the wrapper instead of long-term keys. I'll update the design document to fix this over-reaching terminology.