Hi, everyone,
It’s indeed a very good and necessary idea to implement ECDSA signature alongside the ECIES encryption scheme already present.
However one must be careful to implement it in the best secure way.
Let’s assume Alice is encrypting the file towards Bob’s Gaia hub (not sure it’s the right term here).
As it the proposal is written now, it says “signs the encrypted object”, I guess it means signing the tuple ( Ciphertext, IV, MAC, EphemerealKey )
. Unfortunately, this allows for an attacker (let’s call it Eve to simply strips off the signature, re-signs the tuple under his own private key and sends it again to Bob. Bob would verify the signature and allows the decryption, henceforth allowing Eve to resend that message as many times as she wishes. It can be very problematic for some use case as you can imagine.
Usually, the de-facto standard is to sign-then-encrypt as the following:
- signs the message
s = sign(m)
- appends the signature to the message
m' = m || s
- encrypt the new message
c = ECIES(m')
Unfortunately, there’s still one potential attack: this opens up the possibility of Bob decrypting the ciphertext, and resending it to third party, let’s say Charlie. Charlie would receive a correctly encrypted message signed by Alice, which is not the intended case. The problem here is that the symmetric encryption does not authenticate who’s the sender since Alice generates an ephemeral key for each new encryption.
There’s multiple solutions to this problem, which are discussed at length by Dave Davis in this page. In our case, two makes the most sense:
- Including the recipient’s name (here public key) into the message and do sign-then-encrypt
- Do a double signing: sign-then-encrypt-then-sign.
I think the first approach is simpler in the sense that the message would be stg like m' = m || recipient || signature
. The second approach touches less parts of the message but it requires double signing on the client’s side.
In any case, I strongly recommend the sign-then-encrypt approach with one of the above two solutions.
My 2 cents: go with sign-then-encrypt with the recipient’s public key included in the message.
For the sake of completeness, it’s also possible to use the paradigm: encrypt-then-sign-then-encrypt. So the message would stay the same, no need for stripping information, but it requires a double encryption and signing on the client’s side which may impair performance quite a lot.
I’d be happy to discuss more with you guys, and to help / provide implementation if my time permits it.
Cheers !