The Windows 95 CD Key

Software History  /  Copy Protection  /  1995

The Windows 95
CD Key

Released: August 24, 1995  ·  Key format: XXX-XXXXXXX
Algorithm: modulo-7 digit sum  ·  Cracked: almost immediately
Activation: local only — no server, no internet check

Windows 95 was the most anticipated software release in history. Hundreds of millions of people needed a product key to install it. That key was validated by an algorithm so simple it could be worked out with a pencil. Someone did.

What a product key was supposed to do

By 1995, software piracy was Microsoft's most visible commercial problem. Floppy disks could be copied in minutes. CD-ROMs were harder to duplicate at home but could be shared, rented, or borrowed indefinitely. A product with no barrier between the disc and a working installation was effectively free for anyone willing to obtain a copy through informal channels. Microsoft needed a gate — something that distinguished a paid copy from a copied one.

The solution was the product key: a string of characters printed on the certificate of authenticity bundled with every retail box, that the installer would require before proceeding. In principle, if the key was hard to guess or generate, only legitimate purchasers would have access to a valid one. In 1995, this principle rested on an assumption that turned out to be catastrophically wrong: that the validation algorithm could be kept secret.

Windows 95 had no connection to any Microsoft server during installation. There was no online check, no activation handshake, no phone-home mechanism. The installer simply applied a mathematical test to the key the user typed, and either accepted or rejected it locally. That test — the entire copy protection mechanism for the most important software release of the decade — lived inside the installer executable, readable by anyone patient enough to disassemble it.

The key format

A Windows 95 CD key takes the form

plaintext
XXX-XXXXXXX
: a three-digit prefix, a hyphen, and a seven-digit suffix. Twenty characters in total, ten of which are digits the user has to supply. The key is printed on a sticker on the CD case or the certificate of authenticity — a physical object Microsoft could control the production of, even if they could not control the algorithm that validated it.

535-9210756
Segment A  ·  3 digits 535 Must NOT equal 333, 444, 555, 666, 777, 888, or 999
Segment B  ·  3 digits 921 Part of digit-sum check. First 3 of the 7-digit suffix.
Segment C  ·  4 digits 0756 Last 4 of the 7-digit suffix. Sum of all 7 digits must be divisible by 7.
Full suffix rule: sum of all 7 digits (B + C) ≡ 0 (mod 7)  ·  Last digit must NOT be 0 or > 8

The three-digit prefix — Segment A — was not mathematically validated against the suffix. Its only rule was a blacklist: certain repeated-digit values were explicitly forbidden. The seven-digit suffix carried all the cryptographic weight of the scheme, and that weight amounted to a single modular arithmetic check.

The algorithm: modulo 7

The validation logic applied to the seven-digit suffix is straightforward. Add all seven digits together. If the result is divisible by 7 — that is, if the sum modulo 7 equals zero — the key passes. Additionally, the last digit of the suffix must be neither 0 nor greater than 8. That is the complete mathematical content of Windows 95's copy protection.

win95_validate.py  ·  the full algorithm
def validate_win95_key(key: str) -> bool:
    """
    Validate a Windows 95 product key (format: XXX-XXXXXXX).
    Returns True if the key passes all checks.
    """
    # Strip hyphens and whitespace
    key = key.replace("-", "").strip()

    if len(key) != 10 or not key.isdigit():
        return False

    prefix  = key[:3]     # Segment A: first 3 digits
    suffix  = key[3:]     # Segment B+C: last 7 digits

    # Rule 1 — prefix blacklist (repeated-digit triplets)
    blacklist = {"333", "444", "555",
                 "666", "777", "888", "999"}
    if prefix in blacklist:
        return False

    # Rule 2 — last digit of suffix must be 1–8
    last_digit = int(suffix[-1])
    if last_digit == 0 or last_digit > 8:
        return False

    # Rule 3 — digit sum of suffix must be divisible by 7
    digit_sum = sum(int(d) for d in suffix)
    if digit_sum % 7 != 0:
        return False

    return True  # all checks passed


# Quick test cases
print(validate_win95_key("535-9210756"))  # → True  (9+2+1+0+7+5+6 = 30, 30÷7 = 4r2 ✗)
print(validate_win95_key("535-1234568"))  # → True  (1+2+3+4+5+6+8 = 29 ✗)
print(validate_win95_key("535-7770007"))  # → True  (7+7+7+0+0+0+7 = 28, 28÷7 = 4 ✓)
print(validate_win95_key("555-7770007"))  # → False (prefix "555" is blacklisted)

The modulo-7 constraint means that roughly one in every seven random seven-digit suffixes is valid — before accounting for the last-digit rule. With the last digit constrained to 1–8, approximately one in every 8.75 suffixes passes all checks. The blacklist on the prefix eliminates seven of the one thousand possible three-digit values. The total fraction of valid keys in the key space is roughly 11% — a very large proportion. There was no cryptographic secret to protect.

The validation table
Key Prefix check Last digit Digit sum Sum mod 7 Valid?
111-7770007 pass 7 ✓ 28 0 ✓ ✓ YES
123-0000007 pass 7 ✓ 7 0 ✓ ✓ YES
000-0000007 pass 7 ✓ 7 0 ✓ ✓ YES
555-7770007 FAIL (555) 7 ✓ 28 0 ✓ ✗ NO
123-1234567 pass 7 ✓ 28 0 ✓ ✓ YES
123-1234560 pass 0 ✗ 21 0 ✓ ✗ NO
123-1111111 pass 1 ✓ 7 0 ✓ ✓ YES
123-2222222 pass 2 ✓ 14 0 ✓ ✓ YES
How it was cracked

The Windows 95 installer was a 16-bit executable — a format with well-understood structure and widely available disassembly tools. Within days of the release hitting retail shelves in August 1995, hobbyists and reverse engineers had disassembled the installer and located the validation routine. What they found was not a cryptographic hash, not a public-key signature, not a lookup against an encrypted table. It was a handful of comparison instructions and a division.

The modulo-7 algorithm was published on Usenet and early web forums almost immediately. Key generators — small programs that produced arbitrary valid keys on demand — appeared within weeks. Because the algorithm had no secret component, any key a generator produced was mathematically indistinguishable from a legitimate retail key as far as the installer was concerned. The generator did not crack any cipher or brute-force any hash. It simply ran the validation logic in reverse: pick a random prefix not on the blacklist, pick six random digits for the suffix, compute what the seventh digit must be to make the sum divisible by 7, and output the result.

win95_keygen.py  ·  generating a valid key
import random

def generate_win95_key() -> str:
    blacklist = {333, 444, 555, 666, 777, 888, 999}

    # Segment A: any 3-digit number not on the blacklist
    while True:
        prefix = random.randint(0, 999)
        if prefix not in blacklist:
            break

    # Segments B+C: pick 6 free digits, compute the 7th
    free_digits = [random.randint(0, 9) for _ in range(6)]
    current_sum = sum(free_digits)

    # Last digit must make total divisible by 7, and be 1–8
    for last in range(1, 9):         # try 1 through 8
        if (current_sum + last) % 7 == 0:
            suffix = "".join(str(d) for d in free_digits) + str(last)
            return f"{prefix:03d}-{suffix}"

    # No valid last digit found — retry (rare edge case)
    return generate_win95_key()

# Every key this produces will pass the installer's check.
print(generate_win95_key())

⚠ Why this was worse than no protection

A product key that is trivially generatable is arguably more harmful than no product key at all. It created a false sense of security for Microsoft while providing legitimate users with friction — they had to locate their key sticker — and providing pirates with essentially no friction at all. The key still had to be typed, which was a minor inconvenience, but any key generator running on a 486 could produce a valid key in microseconds.

Why the algorithm was so weak

The weakness of the Windows 95 key is not a story of bad engineers. The people who built the installer knew how to write software. The weakness is a story of mistaken threat model. The validation had to run entirely on the client machine — in 1995, internet connectivity was not universal, and Microsoft had no infrastructure for real-time activation checks across millions of installations. Whatever protection existed had to live in the installer, and whatever lived in the installer could be read.

A cryptographically strong validation would have required a secret — either a key known only to Microsoft, or a lookup in an encrypted table the installer could not construct independently. But the installer was a 16-bit program running on a machine with no connection to the outside world. Any secret baked into the installer was, in principle, extractable by anyone with a disassembler and patience. The algorithm's simplicity may have reflected a deliberate judgment that more complex validation would be just as breakable while being more expensive to implement and harder to explain to tech support when legitimate users mistyped their keys.

Any validation algorithm embedded in the installer is, by definition, reversible. The only question is how long it takes.

The modulo-7 check did serve one legitimate purpose: it caught typos. A user who accidentally transposed two digits in their genuine key would trigger the check, get an error message, and look more carefully at their sticker. This — the original justification for most early product key schemes — was the validation's only real function. It was an input sanitiser dressed up as copy protection, and the costume did not fit.

What came after

Microsoft did not repeat this mistake. Windows 98 used a more complex algorithm involving a longer key and additional structural constraints, though it too was eventually reversed. Windows XP introduced product activation — the installer required a connection to Microsoft's servers, which would check whether the key had been used too many times on distinct hardware configurations. The algorithm became irrelevant: even a valid key could be rejected if the server decided the installation looked suspicious. The validation weight shifted from the algorithm to the server, from a math problem to a policy problem.

Windows Vista and later products moved to the Software Protection Platform, a more sophisticated online activation system with hardware fingerprinting, grace periods, and reactivation flows. The product key was no longer the primary gate — it was one factor among several. The CD key algorithm cracked in 1995 was the last time a Microsoft operating system's copy protection could be reduced to a Python one-liner.

↳ The historical footnote

Windows 95 sold over 40 million copies in its first year. The product key did not stop casual copying, but it may have reinforced the norm that software required a purchase — a social signal rather than a technical barrier. The real protection for Windows 95 was not the algorithm. It was the fact that most people buying a PC in 1995 received Windows pre-installed from the manufacturer, with a valid key already registered. The CD key was a box-retail problem, and box retail was already becoming a secondary channel.

The Windows 95 CD key algorithm is, thirty years later, a fixture of computing history courses and reverse engineering tutorials. It is the cleanest possible illustration of a principle that every security engineer now recites from memory: security through obscurity is not security. If the secret is in the binary, it is not a secret. The check that was supposed to protect the most valuable software in the world in 1995 fits, in its entirety, in a fifteen-line Python function. That is remarkable in a way Microsoft almost certainly did not intend.