decentralized-identity / didcomm-messaging

https://identity.foundation/didcomm-messaging/spec/
Apache License 2.0
167 stars 57 forks source link

DIDComm per se is not ensuring PFS #303

Closed AnomalRoil closed 2 years ago

AnomalRoil commented 3 years ago

While reviewing the spec, I noticed that it says:

Due to the triple Key Derivation algorithm used in ECDH-1PU, all messages sent via DIDComm have weak perfect forward secrecy without any additional security added by the transport layer

This is actually wrong. It doesn't feature a triple key derivation as Signal does.

ECDH-1PU is not providing forward secrecy, nor weak forward secrecy in the case where the recipient static key is compromised. It also does not provide any backward secrecy.

That's because the sender has both an ephemeral key and a static key, and both are combined with only the recipient's long term static key to produce the shared key. This means that if the recipients' private static key is leaked, then all previous and future message meant for that recipient are compromised even without an active adversary.

Since there is no independent key material on the receiver side from one sender to the other (unless they are using dedicated Peer DIDs), compromising the long-term secret keys of the receiving DID allows to decrypt all ciphertexts that were ever sent to the corresponding public key, no matter what sender sent it.

In the Signal case, we have the so-called "one-time prekeys" that are published (and signed) and destroyed after receiving a message to ensure forward secrecy. Once a message has been decrypted on a device, there are no private keys on the device that would still allow to decrypt that message in its encrypted form. This is not the case with DIDComm.

Here, with ECDH-1PU, we are "just" in a C(1e, 2s) key agreement case (as per NIST.SP.800-56A terminology), which does not provide forward secrecy at all, as only C(2e, Xs) key agreements do so using 2 ephemeral keys: on for each party. But these are typically interactive (unless you're publishing unused pre-keys à la Signal to act as your ephemeral keys). The same is true for the ECDH-ES case as it is a C(1e, 1s) scheme.

More generally, we cannot guarantee the following to the receiving party:

Demo

  1. Alice is sending messages M_1, M_2 to Bob
  2. She encrypts the messages with DIDComm to Bob's DID using one of Bob's keyAgreement key
  3. Time flies
  4. Alice sends message M_3 to Bob
  5. Bob gets hacked by Eve, his DID private material is leaked but he doesn't know it
  6. Alice sends message M_4 to Bob

Now, Eve can decrypt all the ciphertexts C_1, ... C_4 corresponding to the messages just using the private key material she recovered in step 5. None of them is protected against this.

This isn't the case on the sender side. If Alice gets hacked instead of Bob in step 5, as long as she properly deleted ephemeral key material after sending each message, we cannot use her long-term keys to decrypt any of the ciphertexts.

Fixing this

There is no easy fix that wouldn't involve significant changes of the DIDComm protocol.


Notice that the lack of forward and backward secrecy also means DIDComm messaging has absolutely no interest for secure messaging, so this is an important issue IMO.

Furthermore it also makes the "expansiveness" of the ECDH-1PU handshake for each message totally unwarranted since it doesn't significantly increase the per-message security anyway.

AnomalRoil commented 3 years ago

@TelegramSam @kdenhartog @Baha-sk @dhh1128 ^ Thoughts?

TelegramSam commented 3 years ago

Discussed in WG 20211011. Need a section in the guide about the assumptions of the discussion around PFS. We should remove the claim in the spec to clarify in the meantime.

AnomalRoil commented 3 years ago

Just to make sure we're on the same line here, not having PFS means DIDComm is either "just" a slow and expensive alternative to TLS, but with less security, or a more modern PGP without much more than newer algorithms built-in.

Indeed, any way that uses the keys in a DID to establish a TLS session is better off the bat, without need for Peer DID or anything fancy. Any connection that is expected to be interactive and not significantly asynchronous should opt for using TLS, IMO. (Do we already have a way of "converting" a DID into a self-signed TLS certificate? If not that might be a good idea to have such a thing.)

There's still the fact that DIDComm is non interactive in its key agreement, and more async friendly, allowing for "messages" to be sent easily across a variety of transports without caring about latency or so. But so is PGP. Actually from a security and feature point of view, PGP is roughly equivalent to DIDComm as far as I can tell. So, I'm not sure if the goal is to propose a "more modern PGP", or if we want to push things further.

Fixing DIDComm to include some kind of forward (and backward) secrecy is possible and might be interesting to do, but it would involve significant changes IMO.

But is that something important or not for DIDComm expected usages? (That's actually related to #245)

TelegramSam commented 3 years ago

Actually from a security and feature point of view, PGP is roughly equivalent to DIDComm as far as I can tell.

Maybe from an encryption standpoint, but not from a transport standpoint and a protocol design standpoint, and other details. I'll have more comments on this later, but needed to point out the misalignment in this comparison.

baha-ai commented 3 years ago

Here, with ECDH-1PU, we are "just" in a C(1e, 2s) key agreement case (as per NIST.SP.800-56A terminology), which does not provide forward secrecy at all, as only C(2e, Xs) key agreements do so using 2 ephemeral keys: on for each party. But these are typically interactive (unless you're publishing unused pre-keys à la Signal to act as your ephemeral keys). The same is true for the ECDH-ES case as it is a C(1e, 1s) scheme.

I believe enhancing ECDH-1PU and ECDH-ES with a recipient epk + sender epk will solve the PFS issue, but it will require an out of band epk keys exchange and define how these keys are used along with the static ones (will it require upgraded ECDH-1PU and ECDH-ES algorithms using an additional kdf with the new recipient epk?). It also entails tying peer DIDs to epks, which means a DID is valid for the duration of an epk which is usually valid for only 1 request. A solution to this would be to create special connection epk field in the DID document for longer lived peer DIDs. The only issue is these epk fields are not that much ephemeral anymore as they're persisted in the DID document.

This is definitely beyond the scope of DIDComm V2 given the timeline and the scope of changes needed to address this issue.

dhh1128 commented 3 years ago

@AnomalRoil : I disagree with your assessment of the impact of this. You are not wrong in your analysis of the inaccurate paragraph or of why our key agreement mechanism does less than what PFS requires. But you are misunderstanding the way that session constructs can manifest in DIDComm. DID rotation is intended to be far, far easier than identity rotation or certificate rotation in TLS. DIDs can be thrown away without resetting a relationship. When that happens, you get perfect forward secrecy -- a co-opted DID today does not allow eavesdropping on old conversations. But this is not obvious when you assume that the only rotation is of something called "static keys," and the mapping for a "session" is a single one-way transmission of one message.

kdenhartog commented 3 years ago

Without a requirement for DID Rotation (even though it's pretty easy) to occur on a regular frequency, I don't think it makes sense to say the protocol has PFS. If we were to consider placing this requirement in scope of the spec I think this would preference methods that can easily be created such as did:key and did:peer over ledger based dids which have delays in rotation or have a certain cost associated with that rotation. I'm not comfortable with making these requirements until we consider the impacts of this design choice further.

alenhorvat commented 2 years ago

What if DIDs are only used for discovery and the 3xdh ((and) double ratchet) is applied for message encryption?

Could the protocol distinguish between interactive (Alice and Bob communicate directly) and non-interactive sessions (Alice and Bob communicate async -- one of them is offline)?

As @AnomalRoil suggested, one could have an interactive protocol if both are online Since DIDComm has mediators and mediator endpoints are/can be listed in the DID Doc., mediators could host the user prekeys (as in Signal)

Would this help to solve the problem?

-- In the libp2p+didcomm demo we worked (are working) on we took the approach summarised above

In the async case, we started to integrate the Signal Protocol (we just started);

(we plan to continue with the work)

TelegramSam commented 2 years ago

I think this kind of approach would work fine for the next version. I'm inclined to defer such changes for a future version.

dhh1128 commented 2 years ago

I propose that PR #307 fixes this, for now -- not that it adds PFS, but that it clarifies what the goals of PFS are, and how those goals might be achievable by users of DIDComm. We can do a more sophisticated fix in a later version.

TelegramSam commented 2 years ago

PR #307 fixes this issue. Discussed WG 20220228.

carez commented 1 year ago

As a way to achieve forward secrecy, I proposed an adaptation of the Double Ratchet algorithm into the DIDComm context. I sent the paper to the RWOT workshop coming up in September. If anybody wants to collaborate on the topic just let me know.