Many people who focus on information security, including myself, have
long considered
Telegram suspicious and untrustworthy.
Now, based on findings
published by the investigative journalism outlet IStories (original
in Russian; English version by OCCRP available here),
and my own analysis of packet captures from Telegram for Android and of
Telegram’s protocol described below, I consider Telegram to be a
indistinguishable from a surveillance honeypot.
Telegram generates a long-term identifier, called
auth_key_id
, on every client device. This identifier
does not change depending on where the client is connecting from.
Telegram’s current protocol, MTProto 2, requires this
long-term identifier to be prepended in cleartext, or at
best trivially obfuscated, to at least some encrypted messages sent
through the network. When perfect forward secrecy is in use, temporary
auth_key_id
s are generated every 24 hours or so, and used
instead the long-term one – but still prepended in cleartext to
encrypted messages. This enables anyone who has sufficient network
visibility and a bit of dedication to identify traffic originating from
a given user device.
It is a surprising and unnecessary protocol design choice, present
neither in Signal nor WhatsApp.
IStories found evidence that all network communication to and from
Telegram’s infrastructure go through a company linked to the Russian
FSB. This would provide the kind of network visibility that combined
with auth_key_id
would allow it to identify traffic coming
from specific users, globally.
In other words, what for years seemed like a protocol design oddity
is now looking more like a deliberate decision to facilitate global
surveillance of all Telegram users by the Russian state, while obscuring
Telegram’s infrastructure provider’s role and providing some measure of
plausible deniability for Telegram itself.
The two decisions Telegram made (choice of infrastructure provider
who happens to cooperate with the Russian FSB, and attaching a cleartext
device identifier to encrypted messages) taken together reinforce
surveillance capability of the FSB considerably more strongly than
either of these decisions would have on its own.
It doesn’t matter if these decisions were made on purpose or
accidentally. Telegram is indistinguishable from a honeypot.
Background: Telegram the
Suspicious
For years Telegram
felt suspicious and acted suspiciously to a lot of people working in
information security. It “rolled it’s own crypto”, MTProto. It
reacted poorly to valid criticism of it. Pavel Durov personally kept
attacking and smearing – in a completely unsubstantiated way – fully
end-to-end encrypted competition like Signal.
Whenever anyone looked closely at MTProto (version 1), they’d scratch
their head. The protocol felt off, but nobody could prove that
it is not secure. Until finally somebody did identify a protocol bug
that was (as one blogger put it) “as close to a
backdoor as they’ve ever seen”, potentially allowing Telegram to
decrypt end-to-end encrypted messages.
Telegram fixed the issue, and then rolled out a second version of
it’s own protocol, MTProto 2. Again, when
people started looking closely at it, it felt off, but so far nobody
has been able to prove there is a problem with encryption.
Earlier I said “fully end-to-end encrypted competition” – that’s
because most communication via Telegram is not end-to-end
encrypted, regardless of what Telegram’s own promotional materials
relentlessly suggest. Only so-called Secret Chats are
end-to-end encrypted, but the UI/UX choices around them make them
unwieldy and impractical to use. Telegram’s UI is designed in such a way
that it basically discourages Secret Chats use. End-to-end encryption is
also not available at all for groups and channels. I dive a bit deeper
into this here.
According to information found by IStories reporters, in 2018 98% of all communication on
Telegram was not end-to-end encrypted. As best as I can tell, today
the situation does not look much better.
At the same time Telegram’s marketing heavily relies on claiming
Telegram is “heavily
encrypted.” It is hard to see this as anything but misleading. It
puts people using the service in danger, by making them think they are
communicating in an end-to-end encrypted manner when they are not –
something I had witnessed myself in the context of people doing
sensitive work.
It’s MTProto 2 all the way
down
According to Telegram’s own documentation, all client-server
communication in the system happens using MTProto 2. Messages that
are not end-to-end encrypted – groupchat messages, channel updates, or
just default so-called “Cloud Chats” – encrypted using MTProto 2 to a
key used for client-server communication (called the “authorization key”
in the documentation), and sent.
If a message is end-to-end encrypted – that is, if it is part of a
Secret Chat – it is first encrypted using MTProto
2 to a key negotiated between the recipient’s device and the sender’s
device. Then, the end-to-end encrypted message is encapsulated in
another MTProto 2 message, this time encrypted with the
“authorization key” used for client-server encryption.
That “authorization key”, used to encrypt messages between a client
and a server, is negotiated once on each device, and it seems valid for
communicating with any server in a the Telegram “datacenter” the
client device got assigned to at registration time, pretty much for the
lifetime of the client on that device.
Telegram’s documentation mentions that “in the future”, under certain
conditions, a client device might be
migrated to a different datacenter, thus negotiating a new
“authorization key”. But in general a client device is assigned to a
Telegram “datacenter” once, using the same long-term “authorization key”
as basis for all Telegram client-server communication.
auth_key_id
Each encrypted MTProto 2 message is prepended with a
cleartext 64-bit value, the auth_key_id
. That
value is derived from the “authorization key” that is being used for
client-server encryption, and is required to be strictly unique within a
Telegram “datacenter”.
In other words, an auth_key_id
derived from the
long-term “authorization key” uniquely identifies a specific Telegram
client device used by a specific Telegram user.
I have verified that when I block the IP address of the specific
server the Telegram client on my device kept connecting to, it will
connect to a different IP address in the same subnet, but use the exact
same long-term auth_key_id
(or the currently active
temporary auth_key_id
, if perfect forward secrecy is used –
I explain this below).
I have also observed that regardless of where in the world the client
on my device is connecting from, it always seems to connect to the same
server IP address, or at least the same subnet, and the
auth_key_id
derived from the same long-term key (or, again,
the currently active temporary “authorization key”) shows up in
cleartext.
The way I checked all this is by observing the same the unencrypted,
long-term or temporary auth_key_id
s in different packet
captures, regardless of where the Telegram client on my device connected
from, or which Telegram server IP it connected to. I changed my external
IP using Tor, and I also tested this without Tor in two geographically
distant locations (Iceland and Poland). I describe my testing setup and
dive into analysis of recorded traffic below.
If someone were able to see all traffic coming to and from Telegram’s
infrastructure, they would be able to track people around the world by
observing their cleartext auth_key_id
s prepended to
MTProto-encrypted messages, thus learning IP addresses used by targets’s
devices at any given time.
They would also be able to reason about who is communicating with
whom, by correlating traffic incoming to and outgoing from Telegram’s
infrastructure based on size and timing, again connecting specific
packets to specific user devices based on auth_key_id
s.
How could that someone connect a specific auth_key_id
with a device of a specific person in the first place? Perhaps it’s as
simple as asking Telegram – the service
provided data on tens of thousands of users just in the first quarter of
2025. It is unclear what data is provided, but it is reasonable to
assume IP addresses (if not auth_key_id
s themselves) and
timestamps are included. IP address and a timestamp would be enough to
associate a person using the service with a cleartext
auth_key_id
from packet captures if one had already
captured the relevant traffic.
Yes, people using Telegram could use Tor or VPNs to obscure their
real IP address. The point I am making here is not that it is impossible
to hide from this kind of surveillance facilitated by Telegram’s
protocol design and choice of infrastructure providers – but rather that
these seemingly unrelated choices of Telegram’s appear to work together
exceptionally well to facilitate that kind of surveillance in the first
place.
Obfuscation
Initially I could not find what I was looking for in my packet
captures. With a bit of digging I understood that sometimes Telegram obfuscates
the packets using a rather trivial scheme. For some reason all
packets in my own captures were obfuscated this way.
Telegram’s documentation is clear that this is not an encryption
scheme, and is only meant to thwart some trivial packet filtering
deployed to block Telegram traffic. I wrote a de-obfuscation tool for
captured Telegram packets to simplify my analysis, which you can find here, along
with basic usage instructions.
I decided to publish this code so that others can reproduce my
results regarding auth_key_id
, and further analyze the
protocol and its implications.
Publishing it does not put Telegram users in any additional danger, I
believe: the obfuscation scheme is trivial, well-documented in
Telegram’s documentation, and already implemtented in countless
open-source libraries. If anyone was listening on the wire they’d have
their own implementation already integrated, optimized, and
deployed.
Perfect
Forward Secrecy and temporary auth_key_ids
MTProto 2 supports
perfect forward secrecy (PFS). Just to be clear: perfect forward
secrecy is not the same thing as end-to-end encryption. PFS is possible
in all MTProto 2 communication (including client-server encryption).
End-to-end encryption in Telegram is only available for Secret
Chats.
When PFS is used, a temporary “authorization key” is negotiated using
the authorization key currently in use, and then the identifier of that
new key (temporary auth_key_id
) is prepended to messages,
instead of the long-term auth_key_id
of the device.
These
temporary keys seem to only be valid for 24 hours. When a temporary
authorization key expires, or is about to expire, a new one is
negotiated using messages encrypted with the old one – and with the old
key’s auth_key_id
prepended in cleartext to them.
As I show later on, this means that anyone who can observe all
communication between Telegram clients and Telegram servers could easily
keep track of these temporary auth_key_id
s associated with
a specific user device, even if PFS is in use and all new temporary
“authorization keys” are negotiated without the use of the long-term,
permanent auth_key_id
of the device.
This is because it is extremely unlikely for the IP address of the
client and the temporary auth_key_id
to both change at the
exact same time. If the client reconnects from a new IP address, it will
use an already-observed auth_key_id
. When a new temporary
auth_key_id
is created, it shows up in the traffic
immediately after the old one is used. Some of the captures below
happened weeks apart, or on from physically distant locations – but the
temporary auth_key_id
s visible in them would have easily
allowed the client device to be identified.
Reinventing TLS, poorly
TLS is broadly deployed, well-understood, gradually improved over
decades, repeatedly audited, and battle-tested. It provides exactly what
is needed for client-server communication in the context of a system
like Telegram – that is, confidentiality and integrity of communication.
TLS supports perfect forward secrecy.
There also is public key infrastructure available, along with
certificate pinning and other facilities that together mean no cleartext
client device key identifier needs to be ever transmitted on the wire.
TLS
is used as transport layer encryption by Signal, for example.
And yet, inexplicably, Telegram decided to mainly use their own
MTProto 2 for the client-server transport, instead of using
tried-and-true TLS. Even though, technically, HTTPS is one
of the possible MTProto 2 transports, but I have not found any
indications of HTTPS being used as a transport layer in any of the
packet captures I have analyzed.
Once the Telegram “authorization key” is negotiated between the
client and a server, it then needs to be identified somehow in the
message so that the receiving side (for example, Telegram’s servers)
knows which key to use to decrypt it. Thus, this identifier,
auth_key_id
, needs to be prepended to messages, in
cleartext.
Additionally, MTProto 2 is somewhat obvious in packet captures,
partially because of sequences of bytes that identify what specific
format is being used in any given case (the protocol supports a dizzying array of
transport and transport
formats). Which is presumably why the obfuscation layer had to be
added, so that relatively trivial packet filtering could be
thwarted.
None of this would have been necessary had Telegram decided to use
TLS for their client-server transport.
TLS is not the only available choice, of course. WhatsApp uses
Noise Pipes, which also seems to avoid
all these pitfalls while providing similar features.
Global capability
This is not the first time attention is being drawn to
auth_key_id
and the possibility to track specific people
based on it. There had been reporting on that before, for
example on how it might have been used by the Russian state to target
Ukrainian partisans in Kherson.
The assumption seems to have always been that this might be a problem
when you’re in Russia or where Russian state can have full network
visibility (for example, through SORM), but if you’re
outside of these areas and connecting to Telegram’s servers physically
located outside of Russia (Telegram makes a
big deal of their global infrastucture hosted in many different
jurisdictions), this is much less of a consideration.
IStories’ reporting shows that the Russian FSB, through Telegram’s
chosen global infrastructure provider, could have access to all traffic
flowing to and from Telegram’s servers, wherever they are physically
located in the world, and wherever the traffic originates from.
Combined with the cleartext long-term auth_key_id
(or
it’s temporary version) on the wire, this would give FSB global
capability of tracking movements of all Telegram users.
Over the years Telegram grew to be extremely popular, particularly in
Russia and Eastern Europe; in
2024 it reportedly had 950 million active accounts worldwide. This
translates into the ability to track physical movements of a huge number
of people, including Russian dissidents, Ukrainian soldiers, Easter
European activists, politicians, and so on.
This also means that every time anyone uses or promotes Telegram,
they are unwittingly supporting this possible surveillance operation, by
strengthening network effects
that pull more people into that network and keep them there. If you use
Telegram in any capacity, you have to contend with your personal
responsibility here, however small you might consider it to be.
Finally, what is really striking to me is that we – the information
security community – have for years been focusing on whether or not
Telegram’s encryption scheme is sound, while the obvious (in retrospect)
issue of surveillance based on metadata was staring us directly in the
face, right there in cleartext in packet dumps.
All the more credit to the investigative journalists from IStories who asked the right
questions, and doggedly seeked out the answers.
Diving into the technical
weeds
Below I dive into the techical details: testing setup I used, a bit
on Telegram’s protocol obfuscation scheme, and finally analysis of
specific packet captures.
My analysis focused on Telegram for Android. I have done my own
packet captures, including during the registration of the Telegram
account I used for this. These captures were performed in short sessions
spread over several weeks, while I was in Iceland and in Poland.
I have also done analysis of packet captures done by others for
IStories’ investigation, of both Telegram Desktop, and Telegram for
Android, including packets captured within Russia. These also supported
my conclusions, but I am not at liberty of sharing the raw data.
Testing setup
The testing set-up I used consisted of a QubesOS machine, on which I
had:
- regular QubesOS networking setup (
sys-net
,
sys-firewall
);
- Tor networking VM (
sys-whonix
);
- packet sniffing VM (
telegram-sniff
);
- Ubuntu VM running Waydroid with
Telegram for Android installed (
telegram-apk
).
I used Telegram for Android, version v11.9.2 (5901). The APK was downloaded directly from Telegram’s
website.
The telegram-apk
VM used the telegram-sniff
VM as its network provider. That in turn used as a network provider
either sys-firewall
(standard QubesOS setup) or
sys-whonix
(when I wanted to route traffic through Tor). I
used Wireshark running in the telegram-sniff
VM to perform
the packet dumps. When I needed to block certain Telegram server IPs, I
did that in the telegram-sniff
VM.
This meant that I could change the underlying networking set-up and
perform packet captures, while making sure the Telegram app had no way
of noticing or interfering with them.
Packet captures
All packet captures discussed below are available here. They contain only
Telegram-related traffic. The filenames contain a UNIX timestamp of the
first packet, and a meaningful description of what was being done while
the packet capture was running.
Most packets I observed turned out to be obfuscated using MTProto 2
obfuscation scheme. As mentioned, I wrote a tool to deobfuscate them and
try to extract auth_key_id
s. Output below is from that
tool.
The tool operates on payload data extracted from the packet dumps.
The only packets that contain auth_key_id
are the initial
data packets of TCP streams. So, to prepare *.payloads
files for the tool to process, we need to:
- identify all complete TCP streams in the packet capture file;
- extract payload data from only the first packet of each stream.
The deobfuscation tool repository contains a short
tshark
-based script that does just that.
Whenever auth_key_id
is printed by the deobfuscation
tool, it means that:
- the data in the packet was in fact obfuscated;
- after de-obfuscating it the data contained the
ef:ef:ef:ef
abridged
transport marker at the expected offset.
An “null” auth_key_id
of
00:00:00:00:00:00:00:00
indicates a message that is not
encrypted or otherwise a service message. Specifically, messages that
are used in the process of negotiating
an authorization key will have auth_key_id
set to all
zeroes.
Each separate packet capture file was captured during a single
session, which means a single external IP address. I am not showing the
IP addresses here, because the captures were done on the internal
QubesOS network, and only involve private network IPv4 addresses.
External IP addresses changed between each session.
Obfuscation
When looking at packet payloads carrying MTProto 2 one should see the
tell-tale markers of one of the many MTProto 2 transport schemes, and
then auth_key_id
a few bytes later (depending on the scheme
in use). But I kept getting random-looking data, for example:
fa:8f:85:46:94:ab:c7:21 3d:9a:31:61:43:f3:34:e6 ed:43:41:fc:9b:c4:65:20 83:27:f5:ff:0c:20:47:e7
de:f1:24:09:39:6d:9a:1f 31:4e:47:b0:1c:be:93:b3 aa:ed:1a:f2:4b:0a:cc:d2 9c:6c:32:90:1c:25:f9:73
29:e1:09:02:e1:3a:da:77 e5:76:53:4b:4c:c6:e4:b9 6d:c7:af:50:16:d4:30:49 8f:4e:c6:50:56:ac:cc:a3
(...)
This meant that the data was obfuscated. When passed through my
deobfuscation library, this payload looks like this:
95:f8:27:6a:d4:e2:2c:82 77:eb:6d:8d:fd:78:4e:2e 78:a0:b5:54:e7:f9:8a:9c 65:3c:04:c1:d5:68:b4:34
79:1c:3d:4e:ec:ae:23:b9 aa:db:73:ce:16:86:09:33 8e:9a:e7:73:6d:1c:ab:1e ef:ef:ef:ef:ed:b2:26:37
2a:64:0a:8a:ff:3a:83:75 54:57:07:07:e2:06:3d:a5 f7:8d:60:f6:a0:48:f3:61 49:f9:2a:3d:1f:ce:1a:df
(...)
Where:
-
ef:ef:ef:ef
is a marker of the “abridged” MTProto 2
transport, when used with obfuscation;
-
ed:b2:26:37
is just random data leftover after
obfuscation (in some cases it can be used for information related to
Telegram’s “datacenters”, but this seems irrelevant here);
-
2a
is the length of actual MTProto 2 message
payload;
-
64:0a:8a:ff:3a:83:75:54
is the
auth_key_id
, at the very beginning of the MTProto 2
message.
Data before the ef:ef:ef:ef
marker is random noise, a
result of “deobfuscating” the key and initialization vector for AES-CTR
used for obfuscation. The key is bytes 8 through 39 of the original
payload (yes, cleartext on the wire – otherwise it would be impossible
to deobfuscate it on the other end), and the initialization vector bytes
40 through 55.
Bytes 0 through 7 seem to only matter for the server as far as it
needs to figure out which transport and format is being used –
basically, they need to not contain certain magic byte sequences to be
treated as obfuscated MTProto 2.
Registration and first
message
We get several potential auth_key_id
s from sniffing
during initial registration:
processing file: 1746314533-telegram-mobile-first-registration-and-message.pcapng.payloads
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 8a:31:86:7d:2e:8e:0c:77
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : c6:00:00:4d:db:fa:12:b8
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : a6:00:00:ae:cf:27:cf:ba
auth_key_id : ae:cf:27:cf:ba:e1:58:d5
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : c7:33:a1:24:02:4f:3c:36
auth_key_id : 58:d6:c4:e6:fa:bb:0b:68
auth_key_id : eb:40:17:49:1e:e4:93:c9
auth_key_id : 64:0a:8a:ff:3a:83:75:54
The only one that repeats several times here – apart from the
00:00:00:00:00:00:00:00
null auth_key_id
– is
64:0a:8a:ff:3a:83:75:54
, so that’s probably the long-term
auth_key_id
. But we should make note of all of them.
Background sessions
Three different background sessions (meaning, without actually
starting the Telegram app explicitly). The telegram-apk
VM
was restarted between these session.
Our suspected long-term auth_key_id
is obviously
visible:
processing file: 1746315509-telegram-mobile-background-session-no-open-app.pcapng.payloads
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : 64:0a:8a:ff:3a:83:75:54
processing file: 1746318794-telegram-mobile-background-session-no-open-app2.pcapng.payloads
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : 64:0a:8a:ff:3a:83:75:54
processing file: 1746319193-telegram-mobile-background-session-no-open-app3.pcapng.payloads
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : 64:0a:8a:ff:3a:83:75:54
Background sessions via Tor
When Tor is used to change the external IP address from which
connections would be established with Telegram servers, again the
suspected long-term auth_key_id
is obviously visible:
processing file: 1746319792-telegram-mobile-background-session-no-open-app-via-tor1.pcapng.payloads
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : 64:0a:8a:ff:3a:83:75:54
processing file: 1746320078-telegram-mobile-background-session-no-open-app-via-tor2.pcapng.payloads
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : 64:0a:8a:ff:3a:83:75:54
This is also true for when I blocked the IP address that the Telegram
app kept connecting to, and then unblocked it again:
processing file: 1746326453-telegram-mobile-background-session-no-open-app-via-tor-91-blocked1.pcapng.payloads
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : 64:0a:8a:ff:3a:83:75:54
processing file: 1746327628-telegram-mobile-background-session-no-open-app-via-tor-after-91-unblocked1.pcapng.payloads
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : 64:0a:8a:ff:3a:83:75:54
Joining a channel
When I joined a channel – while physically located in Poland instead
of Iceland – the long-term auth_key_id
was visible
initially:
processing file: 1747770014-telegram-mobile-open-app-join-minionquote-channel.pcapng.payloads
auth_key_id : 64:0a:8a:ff:3a:83:75:54
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : c7:33:a1:24:02:4f:3c:36
auth_key_id : 58:d6:c4:e6:fa:bb:0b:68
auth_key_id : eb:40:17:49:1e:e4:93:c9
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 20:0d:a0:1e:f7:32:e3:2b
auth_key_id : 4d:db:fa:12:b8:0b:2a:c8
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : ae:cf:27:cf:ba:e1:58:d5
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
auth_key_id : 3c:47:69:e8:ba:09:a3:ff
auth_key_id : f0:f6:f1:07:b1:a7:31:51
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 3c:47:69:e8:ba:09:a3:ff
auth_key_id : 31:b1:e9:42:76:5f:1e:66
auth_key_id : 31:b1:e9:42:76:5f:1e:66
auth_key_id : 31:b1:e9:42:76:5f:1e:66
Seems like this is when perfect forward secrecy kicked in and several
temporary authorization keys were negotiated (as probably indicated by
the all-zero auth_key_id
s followed by new values). Anyone
sniffing my traffic on the wire could have noticed this, while also
observing that all of these new auth_key_id
s show up in
packets from the same IP address as the ones observed beforehand.
Some of the presumably temporary keys (ids:
c7:33:a1:24:02:4f:3c:36
,
58:d6:c4:e6:fa:bb:0b:68
,
eb:40:17:49:1e:e4:93:c9
) show up in earlier capture. Others
(ids: 20:0d:a0:1e:f7:32:e3:2b
,
27:41:c4:eb:5e:b6:b5:63
) turn out to be used later.
Talking to a bot
The next session did not include the presumed long-term
auth_key_id
. That’s consistent with Telegram’s
documentation, that requires the long-term auth_key_id
not
to be used once temporary keys are in use for perfect forward
secrecy:
processing file: 1747770709-telegram-mobile-transparency-for-iceland.pcapng.payloads
auth_key_id : 20:0d:a0:1e:f7:32:e3:2b
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
processing file: 1747773654-telegram-mobile-transparency-for-iceland2.pcapng.payloads
auth_key_id : 20:0d:a0:1e:f7:32:e3:2b
auth_key_id : 20:0d:a0:1e:f7:32:e3:2b
auth_key_id : e5:c2:9a:fd:8d:5a:23:16
auth_key_id : 09:02:40:0f:1a:62:85:89
auth_key_id : e7:ee:21:9f:3b:a4:4a:1d
auth_key_id : 20:0d:a0:1e:f7:32:e3:2b
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
But it did contain two ids (20:0d:a0:1e:f7:32:e3:2b
,
27:41:c4:eb:5e:b6:b5:63
) of the presumably temporary
auth_key_id
s seen before in the same packet capture as the
long-term one.
This was true also when I switched to Tor in order for the connection
to seem to originate from a completely different location:
processing file: 1747787981-telegram-mobile-transparency-for-iceland3-over-tor.pcapng.payloads
auth_key_id : 20:0d:a0:1e:f7:32:e3:2b
auth_key_id : 20:0d:a0:1e:f7:32:e3:2b
auth_key_id : e5:c2:9a:fd:8d:5a:23:16
auth_key_id : 09:02:40:0f:1a:62:85:89
auth_key_id : e7:ee:21:9f:3b:a4:4a:1d
auth_key_id : 20:0d:a0:1e:f7:32:e3:2b
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
In other words, these packet captures, even though they do not
contain the long-term auth_key_id
, can still be easily tied
to the same user: the temporary auth_key_id
s that are
visible here were observed with the long-term one before (associated
with it via IP address). Any new temporary auth_key_id
s
would have been negotiated using the current temporary
auth_key_id
s and could thus be associated with the same
device the same way.
As long as we have the requisite global network visibility. Which,
thanks to Telegram’s choice of infrastructure providers, FSB does seem
to have.
Connecting after a long
break
I took a break for a couple of weeks, to see what would happen with
regards to the temporary auth_key_id
s.
Upon reconnecting, yet again I could observe old temporary
auth_key_id
s (20:0d:a0:1e:f7:32:e3:2b
,
e5:c2:9a:fd:8d:5a:23:16
,
09:02:40:0f:1a:62:85:89
,
e7:ee:21:9f:3b:a4:4a:1d
,
27:41:c4:eb:5e:b6:b5:63
,
31:b1:e9:42:76:5f:1e:66
) closely followed by newly
generated ones (ba:96:5e:72:66:b8:17:91
,
3c:47:69:e8:ba:09:a3:ff
,
02:5a:6b:98:cc:a4:ea:ce
):
processing file: 1749161835-telegram-mobile-transparency-for-iceland4-from-poland.pcapng.payloads
auth_key_id : 20:0d:a0:1e:f7:32:e3:2b
auth_key_id : e5:c2:9a:fd:8d:5a:23:16
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 09:02:40:0f:1a:62:85:89
auth_key_id : e7:ee:21:9f:3b:a4:4a:1d
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : ba:96:5e:72:66:b8:17:91
auth_key_id : ba:96:5e:72:66:b8:17:91
auth_key_id : ba:96:5e:72:66:b8:17:91
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
auth_key_id : 27:41:c4:eb:5e:b6:b5:63
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 31:b1:e9:42:76:5f:1e:66
auth_key_id : 31:b1:e9:42:76:5f:1e:66
auth_key_id : 3c:47:69:e8:ba:09:a3:ff
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 00:00:00:00:00:00:00:00
auth_key_id : 02:5a:6b:98:cc:a4:ea:ce
auth_key_id : 02:5a:6b:98:cc:a4:ea:ce
Conclusions
Based on the analysis of packet captures above, I believe it is clear
that anyone who has sufficient visibility into Telegram’s traffic would
be able to identify and track traffic of specific user devices.
Including when perfect forward secrecy protocol feature is in use.
This would also allow, through some additional analysis based on
timing and packet sizes, to potentially identify who is communicating
with whom using Telegram.