License key security
How license keys get shared, forged or replayed, and the defenses that work: signed answers, replay protection, hashed keys, device secrets, rate limits.
Licensing concepts
A hardware-locked, or node-locked, license is a license key that works only on a limited number of specific devices. The first time the key is used on a computer, the license server records an identifier of that machine; once the license’s device limit is reached, checks from other machines are refused. Machine identifiers can be spoofed, so a sound design pairs them with a secret the server issues to each device.
Last updated
Node-locking ties a license to devices, not to people or networks. A license for one device can be moved to a new computer, but not used on two at once. It differs from floating licensing, where a pool of seats is shared by whoever is using the program at the moment, and from named-user licensing, where a person signs in.
Velsigil implements node-locking with a device limit per plan or license. It does not offer floating seats.
Operating systems already keep a per-installation identifier that applications can read without administrator rights. Velsigil’s SDKs use these:
| Operating system | Source |
|---|---|
| Windows | HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid, read from the 64-bit registry view |
| Linux | /etc/machine-id, then /var/lib/dbus/machine-id |
| macOS | IOPlatformUUID from ioreg -rd1 -c IOPlatformExpertDevice |
All four SDKs (C#, C++, Python and Node.js) derive the same hardware ID from it:
machineId = platform machine id, trimmed and lowercased
hwid = lowercase hex SHA-256("vx-hwid-v1:" + machineId)
hwidHash = SHA-256(hwid) // what the server stores and shows
Other schemes combine hardware serial numbers instead: disk, network adapter, processor or motherboard. Combining components makes an ID harder to fake, but it also changes when a part is replaced or an adapter is added, which turns hardware upgrades into support requests.
A good device identifier stays the same for the life of a device and differs between devices. Real machines do not always cooperate:
For these cases, an application can override the hardware ID with any stable value of 8 to 256 printable characters, for example a value it generates once and stores, or Unity’s SystemInfo.deviceUniqueIdentifier on mobile. It must stay the same for the device: a new value is a new device.
A machine ID is not a secret. Anyone who has a license key and can read the ID of an activated machine can make another computer report the same ID. A hardware ID therefore identifies a device; it does not prove which device is asking.
Velsigil adds a device secret. On the first successful activation, the server issues a random 32-byte secret once and stores only its SHA-256; the SDK saves it on the device and sends it with every later validation, deactivation and download. A copied key with a spoofed hardware ID but without the secret is visible: the server counts a secret mismatch and raises a device_secret_mismatch security event. Copying the secret as well requires access to the original machine’s stored data.
With strict device binding off (the default), a device that presents a wrong or missing secret still validates, but it gets no new secret and every request keeps recording mismatches, so it stays flagged until it is reset. This tolerates users who wiped the application’s data.
With strict binding on, a mismatch is a hard block: the server answers device_verification_failed until the seller or the customer resets or removes the device. The next validation then creates a new activation with a new secret.
| Setting | Default | Effect |
|---|---|---|
| Hardware lock | on | Enforces the maximum number of devices (device_limit_reached). |
| Max activations per day | 10 | New devices per license in a rolling 24 hours; removed and re-added devices count again. |
| Activation cooldown | 0 seconds | Minimum time between two new devices. |
| Strict device binding | off | A secret mismatch becomes a hard block. |
| Customer device reset | on | Customers may reset or remove devices in the portal. |
| Reset cooldown | 24 hours | Minimum time between two portal resets. |
The maximum number of devices comes from the plan (1 by default) and can be overridden per license. Hitting the daily activation limit raises a device_churn event, and more than 10 IP addresses per license within an hour raises suspicious_activation. Detectors flag; they never ban a license automatically.
“I got a new PC” is the most common support request in node-locked licensing. Give customers a way to handle it themselves:
The reset cooldown keeps self-service from becoming a way to rotate one key across many computers.
Removing a device frees its slot, and the device can activate again. Revoking a device is stronger: that hardware ID cannot activate on the license again until staff restore it, and the SDK deletes its stored offline lease at the next signed answer (device_revoked). Banning a license can also blacklist every device on it and the customer’s email address for the product. Blacklists cover hardware IDs, IP addresses or ranges and email addresses, globally or per product.
The hardware ID an SDK sends is already a hash of the machine ID, and the server stores and shows only a second hash of it. The panel and validation logs never show the raw machine ID, and webhook payloads never contain full hardware IDs or raw license keys, though they may contain the customer’s email address. By default, IP addresses are anonymized after 7 days and validation logs are kept for 30 days; the seller can change both under Settings > Retention.
Keep reading
How license keys get shared, forged or replayed, and the defenses that work: signed answers, replay protection, hashed keys, device secrets, rate limits.
How software checks a license without internet: signed offline leases, signed license files, grace periods, clock tampering and what each one trusts.
Validate license keys in Node.js and Electron: signed answers, device secrets, offline leases, and why the check belongs in the main process.
What a self-hosted license key server does, what it needs to run, and how to decide between building, renting or running one yourself on Linux or Windows.
Early access
Early access is free. In exchange, we ask for your feedback while we prepare the paid launch. Spots are limited, and we reply to every request by email.
Early access ends when paid subscriptions launch; we will tell members by email before then. To keep using Velsigil after that, you need a subscription. The 30% discount applies to the first 12 months of either plan, paid monthly or yearly.
Opens your email app with a short template: company, what you sell, your platforms and languages, expected license volume and how you plan to deploy. You can also write to hello@velsigil.com.