Weak PRNG: The Netscape SSL Bug (1994)

A strong cipher is worthless if the key is generated poorly. Netscape Navigator seeded its SSL PRNG with time ^ PID. Both values are observable or guessable by an attacker — collapsing a notional 2¹²⁸ key space to fewer than a million candidates, crackable in seconds.

The weak seed

Unix timestamp
Network packet timestamp reveals this ± 60 s
XOR (^)
Process ID (PID)
???
1994-era Unix: sequential, typically < 1 024
=
Seed →
LCG PRNG
produces the "random" session key bytes

Intercepted SSL handshake

The attacker captures the encrypted SSL CLIENT_HELLO challenge over the wire. The challenge's plaintext structure is fixed by the protocol — zero bytes — giving a known-plaintext pair.

Known plaintext (CLIENT_HELLO challenge)
Intercepted ciphertext

Brute-force the seed

Try every combination of timestamp ± 60 s and PID 1–1 024. For each candidate seed, generate the key, decrypt the challenge, and check whether the result is all-zero. Real hardware in 1994 needed minutes; the browser finishes in milliseconds.

Search space
time window × PID range
Effective entropy
bits
vs 128 bits for a proper key
Attempts so far
0
Speed

How it works

In 1994, Ian Goldberg and David Wagner audited Netscape Navigator's SSL 2.0 implementation. The PRNG was seeded with a combination of the current time (seconds), the browser's process ID, and the parent process ID — all observable or easily guessed by any local process or network adversary with an approximate connection timestamp.

The SSL CLIENT_HELLO challenge is a fixed-format structure whose plaintext content is known to both parties and therefore to an eavesdropper. With a known plaintext and a tiny seed space, the attacker simply iterates every plausible seed, regenerates the key, and checks whether decryption succeeds. On 1994 hardware this took about a minute; on modern hardware it takes microseconds.

This simulation uses an LCG (the glibc rand() parameters) to model the weak PRNG and RC4 to model the stream cipher, matching the conceptual structure of the Netscape flaw.

The lesson is not specific to Netscape: a cryptographically secure PRNG (CSPRNG) is mandatory for key generation. An LCG seeded with observable system values is not random — it is a public function of public inputs, dressed up in complexity. Modern APIs (crypto.getRandomValues, /dev/urandom) exist precisely to avoid this mistake.