https://mjg59.dreamwidth.org/71646.html
Account name: [ ] Password [ ] [Log in]
(OpenID?) (Forgot it?) [ ] Remember Me
You're viewing [personal profile] mjg59's journal
Create a Dreamwidth Account Learn More
[ ] [Interest ] [Go]
Reload page in style: site light
Matthew Garrett
Twitter's new encrypted DMs aren't better than the old ones
Twitter's new encrypted DMs aren't better than the old ones
Jun. 5th, 2025 12:02 pm
[personal profile] mjg59
(Edit: Twitter could improve this significantly with very few changes
- I wrote about that here. It's unclear why they'd launch without
doing that, since it entirely defeats the point of using HSMs)
When Twitter[1] launched encrypted DMs a couple
of years ago, it was the worst kind of end-to-end
encrypted - technically e2ee, but in a way that made it relatively
easy for Twitter to inject new encryption keys and get everyone's
messages anyway. It was also lacking a whole bunch of features such
as "sending pictures", so the entire thing was largely a waste of
time. But a couple of days ago, Elon announced the arrival of
"XChat", a new encrypted message platform `built on Rust with
(Bitcoin style) encryption, whole new architecture'. Maybe this time
they've got it right?
tl;dr - no. Use Signal. Twitter can probably obtain your private
keys, and admit that they can MITM you and have full access to your
metadata.
The new approach is pretty similar to the old one in that it's based
on pretty straightforward and well tested cryptographic primitives,
but merely using good cryptography doesn't mean you end up with a
good solution. This time they've pivoted away from using the
underlying cryptographic primitives directly and into higher level
abstractions, which is probably a good thing. They're using
Libsodium's boxes for message encryption, which is, well, fine? It
doesn't offer forward secrecy (if someone's private key is leaked
then all existing messages can be decrypted) so it's a long way from
the state of the art for a messaging client (Signal's had forward
secrecy for over a decade!), but it's not inherently broken or
anything. It is, however, written in C, not Rust[2].
That's about the extent of the good news. Twitter's old
implementation involved clients generating keypairs and pushing the
public key to Twitter. Each client (a physical device or a browser
instance) had its own private key, and messages were simply encrypted
to every public key associated with an account. This meant that new
devices couldn't decrypt old messages, and also meant there was a
maximum number of supported devices and terrible scaling issues and
it was pretty bad. The new approach generates a keypair and then
stores the private key using the Juicebox protocol. Other devices can
then retrieve the private key.
Doesn't this mean Twitter has the private key? Well, no. There's a
PIN involved, and the PIN is used to generate an encryption key. The
stored copy of the private key is encrypted with that key, so if you
don't know the PIN you can't decrypt the key. So we brute force the
PIN, right? Juicebox actually protects against that - before the
backend will hand over the encrypted key, you have to prove knowledge
of the PIN to it (this is done in a clever way that doesn't directly
reveal the PIN to the backend). If you ask for the key too many times
while providing the wrong PIN, access is locked down.
But this is true only if the Juicebox backend is trustworthy. If the
backend is controlled by someone untrustworthy[3] then they're going
to be able to obtain the encrypted key material (even if it's in an
HSM, they can simply watch what comes out of the HSM when the user
authenticates if there's no validation of the HSM's keys). And now
all they need is the PIN. Turning the PIN into an encryption key is
done using the Argon2id key derivation function, using 32 iterations
and a memory cost of 16MB (the Juicebox white paper says 16KB, but
(a) that's laughably small and (b) the code says 16 * 1024 in an
argument that takes kilobytes), which makes it computationally and
moderately memory expensive to generate the encryption key used to
decrypt the private key. How expensive? Well, on my (not very fast)
laptop, that takes less than 0.2 seconds. How many attempts to I need
to crack the PIN? Twitter's chosen to fix that to 4 digits, so a
maximum of 10,000. You aren't going to need many machines running in
parallel to bring this down to a very small amount of time, at which
point private keys can, to a first approximation, be extracted at
will.
Juicebox attempts to defend against this by supporting sharding your
key over multiple backends, and only requiring a subset of those to
recover the original. [S:I can't find any evidence that Twitter's
does seem to be making use of this,:S]Twitter uses three backends and
requires data from at least two, but all the backends used are under
x.com so are presumably under Twitter's direct control. Trusting the
keystore without needing to trust whoever's hosting it requires a
trustworthy communications mechanism between the client and the
keystore. If the device you're talking to can prove that it's an HSM
that implements the attempt limiting protocol and has no other
mechanism to export the data, this can be made to work. Signal makes
use of something along these lines using Intel SGX for contact list
and settings storage and recovery, and Google and Apple also have
documentation about how they handle this in ways that make it
difficult for them to obtain backed up key material. Twitter has no
documentation of this, and as far as I can tell does nothing to prove
that the backend is in any way trustworthy. (Edit to add: The
Juicebox API does support authenticated communication between the
client and the HSM, but that relies on you having some way to prove
that the public key you're presented with corresponds to a private
key that only exists in the HSM. Twitter gives you the public key
whenever you communicate with them, so even if they've implemented
this properly you can't prove they haven't made up a new key and
MITMed you the next time you retrieve your key)
On the plus side, Juicebox is written in Rust, so Elon's not 100%
wrong. Just mostly wrong.
But ok, at least you've got viable end-to-end encryption even if
someone can put in some (not all that much, really) effort to obtain
your private key and render it all pointless? Actually no, since
you're still relying on the Twitter server to give you the public key
of the other party and there's no out of band mechanism to do that or
verify the authenticity of that public key at present. Twitter can
simply give you a public key where they control the private key,
decrypt the message, and then reencrypt it with the intended
recipient's key and pass it on. The support page makes it clear that
this is a known shortcoming and that it'll be fixed at some point,
but they said that about the original encrypted DM support and it
never was, so that's probably dependent on whether Elon gets
distracted by something else again. And the server knows who and when
you're messaging even if they haven't bothered to break your private
key, so there's a lot of metadata leakage.
Signal doesn't have these shortcomings. Use Signal.
[1] I'll respect their name change once Elon respects his daughter
[2] There are implementations written in Rust, but Twitter's using
the C one with these JNI bindings
[3] Or someone nominally trustworthy but who's been compelled to act
against your interests - even if Elon were absolutely committed to
protecting all his users, his overarching goals for Twitter require
him to have legal presence in multiple jurisdictions that are not
necessarily above placing employees in physical danger if there's a
perception that they could obtain someone's encryption keys
Tags:
* advogato,
* fedora
* Previous Entry
* Add Memory
* Share This Entry
* Next Entry
---------------------------------------------------------------------
* Reply
---------------------------------------------------------------------
Profile
Matthew Garrett
About Matthew
Power management, mobile and firmware developer on Linux. Security
developer at Aurora. Ex-biologist. [personal profile] mjg59 on
Twitter. Content here should not be interpreted as the opinion of my
employer. Also on Mastodon.
Expand Cut Tags
No cut tags
Top of page