DEV Community

Humja Jaan
Humja Jaan

Posted on

How MTProto Obfuscation and FakeTLS Defeat Deep Packet Inspection

Deep Packet Inspection (DPI) blocks Telegram by recognising the unique byte signatures of its transport protocol. Standard MTProto uses a fixed 0xEE prefix on the first packet and specific handshake patterns – easy for state-level filters like Russia's TSPU or Iran's DPI to match and drop. MTProto proxies exist to bypass these filters, and they do it with three layers: obfuscation, random padding, and FakeTLS. Here’s how each works and why DPI can’t keep up.

MTProto Protocol Basics (Transport Layer)

Telegram's transport layer is not vanilla TLS. It uses a custom framing protocol over TCP with its own built-in encryption. The first four bytes of a connection are either:

  • 0xEEEEEEEE for plain (deprecated)
  • 0xEFEFEFEF for abridged (no checksum)
  • Or an intermediate mode with 0xEE prefix

These magic bytes are DPI candy. Filter operators can write a single rule: drop any TCP connection with first byte = 0xEE. That's why raw MTProto connections are blocked in most censored regions.

Obfuscation: Making the First Bytes Random

The simplest evasion wraps the MTProto connection in a thin XOR obfuscation layer. The client sends a random 64-byte "obfuscation envelope" before the actual MTProto handshake. The proxy decrypts it and forwards the inner traffic normally.

The envelope structure:

[client_random (64 bytes)] [encrypted_mtproto_data...]
Enter fullscreen mode Exit fullscreen mode

The first byte of client_random is 0xEF to look like abridged mode to the proxy, but the rest are random. The proxy sends back its own 64-byte random response. After this exchange, both sides derive an XOR key from the random data to obfuscate subsequent packets.

This defeats simple signature-based DPI because the first byte on the wire is no longer a known magic value. However, traffic analysis can still detect the pattern of a 64-byte initial exchange followed by consistent packet sizes – which leads to the next layer.

Random Padding: Blurring Traffic Patterns

Even with XOR obfuscation, the packet sizes of MTProto messages follow a distinct distribution. Telegram's messages are typically small (100–800 bytes for text, larger for media). A series of fixed-size or narrowly varying packets over a TCP connection looks suspicious to statistical DPI.

Random padding fills each obfuscated packet with extra bytes so that the observed size falls into a wider range or matches typical TLS record sizes (e.g., 256, 512, 1024, 1460 bytes). The padding is appended before encryption and discarded after decryption.

A simplified packet flow:

+----------+------------------+-----------+
| Salt (8) | Session ID (8)   | Padding   |
+----------+------------------+-----------+
| Message data (variable)     | Random    |
+-----------------------------+-----------+
Enter fullscreen mode Exit fullscreen mode

The total length after padding is rounded up to a multiple of 16 bytes (for AES block alignment) plus a random offset. This makes it much harder for a DPI box to fingerprint Telegram by packet length alone.

FakeTLS: Wrapping Everything in HTTPS

FakeTLS takes obfuscation further: it wraps the entire MTProto proxy connection in a perfectly valid TLS handshake that mimics a real HTTPS session.

Here's what happens on the wire:

  1. Client sends a ClientHello – containing a random SNI (e.g., cloudflare.com), a standard cipher suite list, TLS 1.2/1.3 version, and random key share data.
  2. Proxy responds with ServerHello – plus a self-signed or real certificate (many FakeTLS proxies fetch a genuine one from Let's Encrypt or use a bundled cert).
  3. TLS handshake completes normally.
  4. Inside the encrypted TLS tunnel, the proxy and client switch to MTProto obfuscated protocol. The DPI sees only encrypted TLS records – all identical in structure to any browser visiting GitHub or Google.

The critical point: passive DPI does not decrypt TLS. It can only inspect the unencrypted handshake fields (SNI, certificate metadata, cipher suite list). FakeTLS proxies craft these fields to match common browsers and services, so the connection looks like normal web traffic.

Most censorship systems use a combination of SNI blacklisting and IP-range blocking. FakeTLS bypasses SNI blocking by using popular, uncensored domain names. It bypasses IP blocking when the proxy runs on an IP not yet in the blacklist.

Why DPI Still Fails – and Where It Might Succeed

FakeTLS is not invincible. Sophisticated DPI like China's Great Firewall performs active probing: after seeing a TLS handshake, it completes a separate connection to the same IP to check if the server actually speaks HTTPS. If it doesn't, the original connection is blocked. Some FakeTLS proxies implement a fallback HTTPS server to pass this test.

Another attack: DPI can correlate packet timing and size patterns inside the encrypted tunnel – but random padding makes that impractical for most operators.

The real advantage of MTProto proxies is the combination of techniques plus frequent IP rotation. By the time a censor adds an IP or pattern to the blocklist, the proxy has moved.

Practical Implications for Developers

If you're building a Telegram client or a proxy management tool, you need to handle three states:

  • Plain MTProto (direct to Telegram server – blocked everywhere)
  • Obfuscated (XOR – works in some regions, not in China)
  • FakeTLS (the gold standard – recommended for all deployments)

For testing, you can generate a proxy link manually:

tg://proxy?server=123.123.123.123&port=443&secret=ee00112233445566778899aabbccddeeff
Enter fullscreen mode Exit fullscreen mode

The secret field starts with ee to indicate obfuscation, or dd for FakeTLS (followed by an SNI encoding). For a deeper analysis of proxy reliability, my earlier testing of hundreds of proxies (published here) showed that FakeTLS proxies have a 40% longer average lifespan than obfuscated ones – precisely because they evade detection longer.

Top comments (0)