libp2p / specs

Technical specifications for the libp2p networking stack
https://libp2p.io
1.56k stars 273 forks source link

noise/: Static key signature does not depend on a peer's challenge #355

Open dnkolegov opened 3 years ago

dnkolegov commented 3 years ago

If an attacker is able to sign a static public key once then they will be able to impersonate the identity key owner forever. This may occur if the attacker has temporary access to a signing module, or if the static key is otherwise compromised.

Libp2p-noise extends the original Noise XX pattern in the following way:

That said, the signature is computed over the sender's static public key without any input from the corresponding peer. So, the used static key authentication mechanism violates the basic authenticated key agreement protocol design principle: Ephemeral leakage should not allow for long-term impersonation.

The initiator does not provide any challenge (e.g., ephemeral key) for signing and sender always signs its static key without any random input from the peer. Actually, the sender just prooves that he or she has a signature over the static public key, but not access to the identity private key. For example, if an attacker finds a triple (s_pub, s_priv, Sig(id, s_pub)) for the identity key id of the target user then he or she will be able to impersonate that user without any limitation in future.

yusefnapora commented 3 years ago

Thanks @dnkolegov - I think you're correct, and it's likely a result of my flawed understanding of Noise when we were speccing this out.

It seems like the simplest way to fix this without drastically rewriting the protocol would be to mandate that the "static" noise key be truly ephemeral, instead of allowing it to be reused between sessions.

dnkolegov commented 3 years ago

Hi @yusefnapora.

It seems like the simplest way to fix this without drastically rewriting the protocol would be to mandate that the "static" noise key be truly ephemeral

I think that's correct.

Another mitigation could be using a peer's ephemeral public key (re) as an unpredictable challenge in signing data = "noise-libp2p-static-key : " || re || s. This is not a "drastically rewriting", but it will require changing the code a little bit.

dryajov commented 2 years ago

Another mitigation could be using a peer's ephemeral public key (re) as an unpredictable challenge in signing data = "noise-libp2p-static-key : " || re || s. This is not a "drastically rewriting", but it will require changing the code a little bit.

I think this is the only real mitigation, the the "static" noise key be truly ephemeral, wouldn't really mitigate the impersonation issue as described by @dnkolegov.