He says that is impossible and you need B's key to impersonate B when talking to A.
Could anyone that knows more about this than I do step in to clarify? Thanks!
He says that is impossible and you need B's key to impersonate B when talking to A.
Could anyone that knows more about this than I do step in to clarify? Thanks!
To do an exchange, you send me A, and I send you B. You compute the DH exchange with B and a, and I compute it with A and b. The important property of the DH function is that computing DH(B,a) is the same thing as computing DH(A,b).
Now, if I steal your secret key 'a', I can do two things. One, I can obviously impersonate you. But two, I can impersonate anyone else, because I can calculate the shared secret. The reason for this is that I need your private key, but I only need the other parties public key.
Let's say you try to communicate with me now and someone has stolen 'a'. They can already have my public key, B, because it is public. Thus, when the exchange happens, you send me A. The attacker knows the secret key, 'a', already. So the attacker can intercept the communication, calculate the DH exchange of 'a' (which they stole) and 'B' (my public key), and they have calculated the shared secret. It is not possible for you to tell you have exchanged with the attacker, and not me. They never need my private key, only my public key, which will come through during the handshake. So it can always be intercepted. Remember, DH(B,a) and DH(A,b) are the same, so if both sides calculate DH(B,a), that's completely legitimate.
This is a very simplified view (and I haven't looked at the bug report in detail, TBQH, so the case for Tox is probably slightly different), but it explains why if your keys are stolen, anyone can be impersonated to you: because the impersonator only needs public information (public keys) from that point on to forge any exchange.
Alice's long-term static keypair is S_A/s_a
Alice's long-term static public key signature(signed by a trusted third party) is sign_A
Bob's long-term static keypair is S_B/s_b
Bob's long-term static public key signature(signed by a trusted third party) is sign_B
Alice's per-session ephemeral keypair is E_A/e_a
Bob's per-session ephemeral keypair is E_B/e_b
Alice sends S_A|sign_A|E_A|sign(data=E_A, key=s_a)
Bob sends S_B|sign_B|E_B|sign(data=E_B, key=s_b)
Shared key is generated with kdf(ecdh(E_A, e_b)) == kdf(ecdh(E_B, e_a))
Would this be vulnerable to KCI?The handshake depends on forming a shared secret. They do by computing an ECDH, which has the property:
ECDH(private A, public B) = ECDH(private B, public A)
So, if you control private A, you can form the shared secret that A relies on for verifying anybody else's identity. Reasonable AKEs protect against this; Tox's naive one does not. So, instead of requiring two compromised keys for a man in the middle between one peer pairs (A<-->B), you only need one compromised key for a man in the middle between infinite key pairs (A<-->{everybody}).