Why Looking Random Is Not the Same as Looking Normal

A fully encrypted stream with no structure does not blend into traffic — it forms a class of its own. Why removing a signature does not deliver indistinguishability.

2026-08-31 GIGATAP Team #vpn
#vpn#anticensorship#obfuscation#traffic-analysis#shadowsocks

Why Looking Random Is Not the Same as Looking Normal

Intuitively, the ideal disguise seems to be a stream indistinguishable from random bytes. No headers, no recognisable fields, no structure: nothing to grab hold of. In practice it is the reverse: the absence of structure is itself a structure, and it is the easiest way to separate an unusual connection from an ordinary one.

The intuition is wrong, and the way it is wrong shapes a whole family of design decisions.

Classification by elimination#

The error is in how the problem is framed. A censor does not need to identify your protocol. It is enough to establish that it is not one of the known permitted ones.

Research presented at USENIX Security in 2023 described a working classifier for fully encrypted traffic. It used features that require no understanding of content:

  • the fraction of set bits in the first payload packet;
  • the fraction of printable ASCII characters;
  • where those characters sit inside the packet;
  • the absence of markers belonging to known protocols.

The logic is simple: if this is not TLS, not QUIC, not SSH, not DNS — and it looks high-entropy — it is suspicious.

Ordinary internet consists of protocols with structure. A stream without structure does not dissolve into it; it stands out against it.

Which forces two goals apart#

It helps to separate two properties that are routinely conflated.

Property What it means What it defeats
Signature removal no fixed bytes by which the protocol is recognised signature matching
Indistinguishability the stream is statistically like a permitted class feature-based classification

The first does not imply the second. A protocol can contain not one constant byte and still land in the “unknown high-entropy” class on the first attempt.

The history of Shadowsocks is a textbook case of that transition. Early versions were caught by content. Once the content-level traits were removed, the censor moved to classifying the first encrypted packets statistically — and kept catching them.

The cost of error, for the censor#

There is an important detail here that explains why such classifiers are applied cautiously.

The authors of that same research estimated that applying their reconstructed rules directly would affect about 0.6% of ordinary TCP connections.

Half a percent sounds small until you convert it into absolute numbers at national scale. That is the censor’s base-rate problem: when the sought traffic is a small share of the whole, even an accurate classifier produces an unacceptable volume of false positives.

Hence a practical corollary: an error that is expensive for the censor is your protection. The more ordinary traffic a rule would damage, the more cautiously it gets applied.

Walkthrough: what classification by elimination looks like#

The classifier’s logic fits into a short tree. Note that the question “is this a proxy?” never appears in it.

first payload packet of the connection
        │
        ├─ TLS marker present?     ─yes─► parse TLS, inspect the name
        ├─ QUIC marker present?    ─yes─► parse QUIC
        ├─ looks like SSH?         ─yes─► let through
        ├─ looks like DNS?         ─yes─► let through
        │
        └─ no marker at all
                │
                ├─ printable ASCII fraction low?  ─┐
                ├─ bits evenly distributed?       ─┼─► "unknown
                └─ no visible structure?          ─┘    high-entropy"
                                                            │
                                                            ▼
                                                        suspicious

A perfectly random stream travels this path all the way down and lands in the final category. Not because it was identified, but because it matched nothing known.

Ordinary HTTPS never gets that far: it is filtered out at the first branch.

A numeric example: why half a percent is a lot#

A false-positive estimate of 0.6% sounds harmless until it is converted into absolute figures.

Connections per day at an average operator hundreds of millions
False-positive rate 0.6%
Ordinary connections affected millions per day

That is precisely why such rules are applied cautiously rather than universally.

Which leads to a direct design consequence. Compare two transports from the censor’s side:

Transport False positives if blocked The censor’s decision
A random stream on a dedicated port almost none — narrow class cheap to block
Genuine HTTPS on 443 millions of ordinary sessions expensive to block

Hence a criterion more useful than “how well are we hidden”: how much of everybody else’s traffic breaks if they decide to block us anyway. The more, the stronger the position — and that is a property of architecture, not of disguise quality.

Two poles of design#

Two opposite strategies grow out of this, and both are viable.

The randomness pole. The stream aims to be indistinguishable from random bytes, and active probing gets no confirming response. Strong against signatures and against probing, weak against the model “unknown means suspicious”.

The mimicry pole. The transport uses a genuinely widespread protocol — not imitating its bytes but actually being it. The censor is forced to distinguish valid behaviour of a permitted protocol from other valid behaviour of the same protocol.

The second approach costs more to deploy, but it has a property the first lacks: the cost of error shifts onto the censor. Blocking a poorly disguised stream is cheap. Blocking something indistinguishable from mainstream web traffic means damaging mainstream web traffic.

Why does random padding not save you?#

A frequent mistake is assuming that adding random padding solves the problem. Padding changes lengths but adds no structure, and classification by elimination reacts precisely to the absence of structure.

Work presented at USENIX Security in 2024 showed the limit of that approach: random padding destroys exact size signatures but does not hide the overall shape — the sequence of bursts, the directions, the number of round trips before useful data flows.

In particular, a nested secure connection inside a tunnel leaves an observable trace that survives various kinds of padding. Growing every packet by a random number of bytes is not enough if the outer stream still shows that another handshake just took place inside.

The maximum-entropy trap#

Which leads to a counter-intuitive conclusion.

The right goal for padding is not maximum randomness but matching the distribution of the cover. Uniform random jitter across a range does not make a stream look like a browser’s — it makes it look like a stream with uniform random jitter, which is its own recognisable trait.

Generalised: obfuscation that exceeds the normal behaviour of its own layer creates a new signal instead of hiding the old one.

A vivid example from a neighbouring area: disguise settings where junk packets exceed the path MTU and cause fragmentation. Fragmentation is rare in ordinary traffic, so the disguise produces exactly what it was meant to prevent.

What follows practically#

State the goal as “resembles a permitted class”, not “resembles nothing”. The second formulation produces a distinct class, and a distinct class is easy to describe with a rule.

Test for distinguishability, not for the presence of a signature. “Do we have constant bytes” answers the wrong question. The right one is “can a simple classifier separate our stream from a corpus of ordinary traffic”.

Start with interpretable models. If a decision tree over the first eight packets confidently separates your transport from ordinary HTTPS, sophisticated defences are premature: the transport has a coarse fingerprint, and that has to go first.

Conclusion#

“Looks random” and “looks normal” are different properties, and the second is harder.

Randomness protects against someone searching for the known. It does not protect against someone searching for the unknown — and that framing turned out to be both cheaper and more practical for a censor.

The transport that lasts is not the one that hides best, but the one whose blocking costs the blocker most.

Terms#

  • Classification by elimination - an approach that treats anything not recognised as a known protocol as suspicious.
  • Cost of error - the damage a blocker takes from restricting legitimate traffic — the quantity that limits how strict rules can be.
  • Maximum-entropy trap - the state where perfect randomness makes a stream more conspicuous rather than less.

FAQ#

Is a random stream not the perfect disguise?#

No. Ordinary traffic does not look random, so perfect randomness lands in the “unknown” category rather than the “ordinary” one.

Why does padding not solve it?#

It changes sizes but adds no structure. Unrecognised stays unrecognised, whatever the distribution of lengths.

What works instead?#

Resembling a permitted protocol rather than resembling nothing. The goal is to land in a known category, not to stay outside all of them.

Further reading#