jitsi / lib-jitsi-meet

A low-level JS video API that allows adding a completely custom video experience to web apps.
Apache License 2.0
1.34k stars 1.11k forks source link

Current E2EE encryption scheme is weak #1201

Open simo5 opened 4 years ago

simo5 commented 4 years ago

The E2EE document describe a scheme where PBKDf2 is used on a ''private'' URL to derive an initial encryption scheme. This is weak in various ways:

plus it does not allow repudiation, once you have the URL you can, also retroactively start decoding streams, and you cannot prevent access to the streams without terminating the meeting and sharing a whole new secret URL.

A better method to handle E2EE which would allow to turn it on at any given time is the following:

  1. Generate ECC keys on each client and publish the public key to all participants
  2. Users ask the host for authorization to join the encrypted stream.
  3. On Host approval an ECDH exchange happens between the user and the host clients and then the actual encryption key, which is randomly generated, not derived, is exchanged encrypted (for example via AES-KW) in the Key negotiated via ECDH.

What all these steps give you? (1) A. gives you the ability to freely share meeting URLs w/o fear of accidentally giving access to the encrypted stream because the host (or by proxy other meeting members if authorized) can always control whether they want to give access to a participant. B. requires active participation in order to access the stream, no hidden observers using stolen URLs. C. It allows the client to show a public key (or fingerprint) for each participant before authorization is granted so that out of band methods (if wanted) can be used by participants to authenticate each other. For example by pasting the public key in a 3rd party chat where participants already trust each other (say via IRC/signal/whatsapp/slack/etc...) D. allows also private conversation between individual participants so that other participants can't see what individuals exchange with each other. (additional ECDH between just the 2 participant allows this) E. When a participant leaves the stream a key rotation can occur so that said participant is cryptographically excluded from the rest of the meeting.

(2) A. allows converting a meeting to encrypted at any time, just signal to clients they need to start the ECDH dance and switch to encrypted scheme right away without interruption of the stream. Existing participants can be pre-approved by the host' client. B. any participant is allowed to add new participants to alleviate the need for the host to approve every single client, if this is unwanted it would require the host to encrypt each video stream multiple times with a different key for each participant, could be considered in future, but not in scope for current scheme either.

(3) A. This is the bit that gives you forward secrecy, as the key exchanged via ECDH is never transmitted so that an attacker cannot decrypt the stream even after the fact. Frequent rotation means an attacker needs to brute force multiple AES keys or needs to break at least one participant ECC key. B. this gives you for free the ability to rekey, that you mention in the doc and say you can't implement yet.

Additionally

For (1) you have 2 options. 1.a: Client generates new ECC keys for each meeting 1.b: client stores keys in browser storage for reuse over multiple meetings

In 1.a you avoid key reuse and reduce the chance of exposing keys that can be used to brute force older recorded streams. However it means the host needs to re-approve individual participant on each meeting. This can be mitigated by additional authentication schemes on top.

In 1.b you can allow the host to pre-authorize in their client configuration specific individuals to join a E2EE meeting at any time, without explicit interaction.

Note: ECC and ECDH are just a choice, you could equally use DH or RSA key exchanges to the same effect, and in future PQC safe algorithms, ECC/ECDH are just currently the most efficient in terms of key sizes and key generation. X25519, X448 or any of the NIST curves could be supported. Supporting multiple key types at the same time may be complicated, but it can be handled in the ephemeral case and with an additional layer of ephemeral key negotiation, it is probably sufficient to standardize on a single curve like x25519 initially.

saghul commented 4 years ago

Hey there! Thanks for the feedback!

  • It relies on keeping a URL secret

  • It relies on keeping a URL secret forever

The URL parameter is just a quick way to change it. We now have some proper UI to change the key:

Screenshot 2020-06-03 at 16 27 07
* it does not allow key rotation

That is coming. We are now working on using olm for key distribution, and once we have it in place the plan is to rotate keys when a participant joins or leaves.

* it does not allow to change meeting mode at will

Not sure what you mean, can you please clarify?

plus it does not allow repudiation, once you have the URL you can, also retroactively start decoding streams, and you cannot prevent access to the streams without terminating the meeting and sharing a whole new secret URL.

As I mentioned the plan is to do automatic key rotation. The URL parameter is our current prototype, but won't be the final solution.

A better method to handle E2EE which would allow to turn it on at any given time is the following:

What you describe is similar to what we gain with the introduction of olm, plus authentication. Our next step, with the introduction of olm is to make E2EE work with randomly generated keys, per-participant, which are automatically rotated. This should give us unverified E2EE. Then we'll add authentication into the mix. This may take different forms, since meet.jit.si is anonymous for example, so while E2EE would be unverified it also provides plausible deniability. This part is still in the works, so stay tuned! Thanks again for the feedback!
iamveritas commented 4 years ago

I do not see the "Enable end-to-end encryption (Beta)" option in my settings...? what am I msising? also if my fellow is enabling it, I see/hear garbage, the question is how can I join in though?

luixxiul commented 4 years ago

@iamveritas please go to https://community.jitsi.org/ for questions, thanks.

Serphentas commented 4 years ago

Kinda related to OP's message:

  1. Why choose AES-GCM which has a data limit (depends on encryption parameters) along with some delicate settings to ensure proper security (as per NIST SP 800-38D), when other ciphers such as ChaCha20+Poly1305 could help avoiding such complications ?
  2. Why use PBKDF2 which can be easily attacked on cheap hardware, when other KDFs such as scrypt or Argon2 can yield harder break requirements thus making the encryption key much safer ?
simo5 commented 4 years ago

I have answers for you:

  1. AES-GCM has good, widespread, HW acceleration and it is a good scheme when you change key on every stream, it's proper use is not really difficult, in this setting, esp if AES-GCM is used with an IV in counter mode and the IV generation is deferred to the underlying crypto module as recommended by NIST.

  2. PBKDF2 is a good key derivation function, but is redundant, neither PBKDF2 nor Argon2 should be needed at all. Argon2 is definitely not a good fit for this use case, as it is very slow (intentionally so) or very memory hard, so not friendly to IoT and similar devices. It is meant for long term keys hashing, so that it is hard to brute force passwords, not really for key derivation, I would use neither PBKDF2 nor Argon2 to derive keys from a random secret (which is what the URL should really contain), but rather a lighter SP 800-108 KDF

Finally both AES-GCM and PBKDF2 are FIPS approved algorithms, meaning they get a lot more scrutiny as well as they are the only algorithms that can be used on systems that must use only FIPS approved algorithms. Although I have nothing against ChaCha20+Poly1305, it would be good to provide support for ciphers that can be used in those cases.

simo5 commented 4 years ago

@saghul

* it does not allow to change meeting mode at will

Not sure what you mean, can you please clarify?

A key negotiation scheme like the one I mentioned, allows you to turn a regular meeting, into an E2EE meeting w/o having to share a new URL for people to join.

You can start a meeting in clear text, then decide you want more privacy and switch E2EE on. The host (or whoever) can do this by simply signaling at runtime, all other clients that you want to switch to a E2EE meeting. Once the signal is received all clients can start a ECDH exchange with the host to set up a secure channel and receive a randomly generated key for the stream. The same mechanism can then be used to re-key at any given time, allowing each re-key to set up a completely new random key that cannot be recovered from the stream itself (forward secrecy), or any URL that can be cached or stored, even temporarily in any client's browser logfile or whatever.

plus it does not allow repudiation, once you have the URL you can, also retroactively start decoding streams, and you cannot prevent access to the streams without terminating the meeting and sharing a whole new secret URL.

As I mentioned the plan is to do automatic key rotation. The URL parameter is our current prototype, but won't be the final solution.

A better method to handle E2EE which would allow to turn it on at any given time is the following:

What you describe is similar to what we gain with the introduction of olm, plus authentication.

Our next step, with the introduction of olm is to make E2EE work with randomly generated keys, per-participant, which are automatically rotated.

This should give us unverified E2EE.

Then we'll add authentication into the mix. This may take different forms, since meet.jit.si is anonymous for example, so while E2EE would be unverified it also provides plausible deniability. This part is still in the works, so stay tuned!

Thanks again for the feedback!