Why You Shouldn't Use Symmetric Encryption to Generate License Keys
· SoftActivate Technical Staff
Licensing Cryptography Software Protection
AES and Blowfish look tempting for short license keys, but a single reverse-engineered binary hands attackers a working keygen for every customer you ever sold to. Here is why digital signatures are the only safe choice.
When developers first sit down to design a license-key system, the temptation is almost universal: reach for a familiar symmetric algorithm — AES, Blowfish, maybe DES if the codebase is old enough — encrypt a small payload, ship it as the license key, and decrypt at the customer's machine to validate.
It looks elegant. It is fast. It even compiles. And it is, almost without exception, the wrong choice. This article explains exactly why, and what to use instead.
The naïve approach
The textbook version of "encrypt my license key" usually looks like this:
KEY = KEY_DATA | ENCRYPTED(HASH(KEY_DATA))
ENCRYPTED = AES-128 / Blowfish / 3DES / "rolled my own"
SECRET KEY = a constant compiled into the product binary
To validate a key at runtime, the product:
- Splits the key into the data portion and the encrypted-hash portion.
- Hashes the data portion locally.
- Decrypts the encrypted-hash portion with the secret embedded in the binary.
- Compares. If they match, the key is "authentic".
This is, structurally, a poor man's digital signature — except that the "signing key" and the "verification key" are the same secret, and that one secret has to live inside every copy of your product you have ever shipped.
The "secret in the binary" fiction
If you have spent any time around reverse engineering, you already know where this is going. A symmetric key sitting inside a shipped executable is not secret. It is, at most, lightly obscured.
A determined attacker with Ghidra, IDA, or dnSpy needs hours, not weeks, to:
- Identify the validation routine (it has a recognisable shape: hash, decrypt, compare).
- Set a breakpoint on the decryption function call.
- Read the key out of memory or out of the static-data segment.
Obfuscation, code packing, anti-debug tricks, white-box cryptography — none of them change the fundamental problem. They raise the cost from a single afternoon to a few afternoons. For a product worth pirating, that is not nearly enough.
The blast radius is your entire customer base
The really bad part is what happens after the secret leaks. With a symmetric scheme:
- The leaked key is the same key every customer's installation uses to validate. There is no per-customer rotation possible after the fact.
- Anyone who downloads the leaked secret can mint unlimited working license keys instantly. Keygens appear on warez sites within days.
- Your only remediation is to change the secret and ship a new build, and hope every paying customer upgrades quickly. In the meantime, support is flooded with calls from legitimate buyers whose newly-purchased keys do not work in their old installation.
The economics are brutal. One reverse-engineering session, one keygen post, and your licensing system is permanently compromised for every version of the product currently in the wild. A new release does not undo the damage to the old one.
And then there is the key length problem
Even setting aside the security disaster, the most common symmetric algorithm of the modern era — AES — is structurally unsuitable for short license keys. AES has a 128-bit block size. The smallest possible AES ciphertext is 16 bytes. Add a hash payload to it and you are already at 32 bytes of binary data, which becomes 52 characters in Base32 — and that is before you add any product-side payload like edition, expiry, or seat count.
No customer wants to type a 52-character key from a printed invoice. No support agent wants to read one over the phone. The block-size mismatch alone is a usability killer.
Older 64-bit-block ciphers like Blowfish at least produce short enough output to be typeable, which is why you still occasionally see them in legacy licensing libraries. The reverse-engineering problem, of course, is identical.
What you actually want
The thing developers reach for symmetric encryption to do — produce a small payload that the product can confirm was issued by you — is a textbook description of a digital signature. The key insight is that signing and verification can use different keys:
- The private key stays on your build server. It never ships. It generates new license keys.
- The public key ships inside every copy of your product. It can verify signatures, but it cannot create new ones.
A leaked public key is worthless to a pirate. They can use it to verify keys to their heart's content, but they cannot mint new ones. The catastrophic "single secret protects every install" failure mode of symmetric schemes disappears completely.
The standard objection is signature size — a 2048-bit RSA signature is 256 bytes, which is far too large to be a typeable license key. That is true, and it is the reason naïve developers go back to symmetric encryption in the first place. The actual answer — short signatures with strong security — is elliptic-curve cryptography, and we cover it in detail in the follow-up article: ECC vs RSA for License Keys.
Bottom line
If your license-key system uses the same secret to issue keys and to validate them, you are one reverse-engineering session away from shipping a free keygen with your product.
Use digital signatures. Keep the private key off the customer's machine. The moment you internalise this, every other licensing decision gets easier.
For a deeper walkthrough of the full design space — including hardware fingerprinting, online activation, and how to keep the resulting keys short enough to type — see our pillar guide: How To Generate License Keys Securely.
If you would rather skip the cryptography homework and ship something that already gets this right, the SoftActivate Licensing SDK includes the full ECC-based key generation pipeline (with C++ and C#/.NET source code) and an interactive license designer you can experiment with in your browser.
About SoftActivate Licensing SDK — a highly secure software licensing and copy protection framework for Windows, Linux, OS X, and Android, with full C++ and C#/.NET source code.