How to Generate License Keys for Your Software (with Code)
Learn how to generate license keys in C#, Python and Node.js, choose random or signed keys, and connect generation to secure validation.
To generate license keys, use a cryptographically secure random generator, encode the bytes in a format your customers can copy, and attach each key to an entitlement record. That last step matters: a random string becomes a license only when your software has a trustworthy way to check what it authorizes.
This guide covers the key-generation code. For the surrounding API, activation limits and concurrent requests, follow the license key system architecture guide.
Choose random keys or signed licenses
| Approach | What the customer receives | How the app checks it |
|---|---|---|
| Random key | An opaque identifier with no embedded permissions | Your server looks up the associated license and current entitlement |
| Signed license | A payload containing entitlements and a digital signature | The app verifies the signature against an independently trusted public key, then checks the payload and deadlines |
Random keys are convenient for online activation, changing features and revoking access centrally. Signed licenses support verification without contacting the server, but their payload is usually readable. A signature proves authenticity; it does not encrypt the contents. Many systems combine a short customer-facing key with a signed offline proof issued after activation.
Generate a random license key in C#
The following complete console example generates 32 random bytes and encodes them as unpadded Base64url. It prints a 43-character string:
using System;
using System.Security.Cryptography;
byte[] bytes = RandomNumberGenerator.GetBytes(32);
string key = Convert.ToBase64String(bytes)
.TrimEnd('=')
.Replace('+', '-')
.Replace('/', '_');
Console.WriteLine(key);RandomNumberGenerator.GetBytes uses cryptographically strong randomness. Keep this generation step on a trusted issuance path; do not put an administrative API credential in your distributed desktop app.
Generate a random license key in Python
import secrets
key = secrets.token_urlsafe(32)
print(key)Use Python's secrets module for security tokens. Passing 32 explicitly fixes the number of random bytes rather than relying on a default that could change. The output has the same 43-character format as the C# example.
Generate a random license key in Node.js
const { randomBytes } = require('node:crypto');
const key = randomBytes(32).toString('base64url');
console.log(key);Node's crypto.randomBytes supplies the random bytes; base64url handles the encoding. These examples share a format, not a deterministic output: each invocation should create a new value.
All three examples start with 256 random bits. Encoding adds no entropy. Base64url is case-sensitive, and its - and _ characters are data: do not lowercase the result or remove those characters during validation. If customers must type keys manually, choose a separate readable alphabet and enough random characters, then define any separators and normalization consistently on issuance and lookup.
Turn the generated string into an actual license
- Create an entitlement record containing the product, customer association, features, expiry and activation policy. Enforce uniqueness for the lookup identifier in your database; retry issuance if a uniqueness constraint rejects a collision.
- Store a protected lookup value rather than copying raw keys into logs, analytics or support tickets. A keyed hash such as HMAC can separate the database from the server-held lookup secret. An identifier generated above does not itself implement hashing, encryption or secure delivery.
- Validate over HTTPS against the server record and apply the product and access rules. Make seat allocation atomic rather than trusting a local counter or a client-supplied entitlement.
- Issue only after an authorized administrative action or verified payment. A successful redirect alone is not payment evidence. Decide how revocation, refunds and renewals affect the existing license.
The full PermitCore storage and lookup boundary is described in the security reference. Keep the distinction between protected storage and online validation: an online request can send the plaintext key transiently for validation even when the database does not store plaintext keys.
When to use signed license keys and ECDSA
A signed license carries an authenticated payload, not just a random serial number. With ECDSA, issuance uses a private signing key and verification uses a public key. Keep the private key on the issuance side. Provision the expected public key independently; a key bundled inside an editable license file cannot establish its own authority.
Use maintained cryptographic libraries and a defined signed format rather than inventing a signature scheme. Verify the original signature before trusting the payload, then check the product, device or customer binding and the effective deadline on every read. An intact signature on an expired license is still an expired license. Test modified payloads, unknown signing keys, wrong contexts and expiry, not just successful signatures.
PermitCore's offline proofs use ECDSA P-256 and configured tenant public-key trust in the SDKs. Follow the offline licensing guide for the supported format and migration rules. Offline verification cannot instantly learn that a server revoked a license; its validity is bounded by the signed deadline and the configured policy.
Using these examples with PermitCore
These snippets are general-purpose key generators. They do not create PermitCore licenses, match its customer-facing key format, or produce valid signed offline tokens. For a PermitCore license, use the built-in Admin issuance workflow or Store payment fulfillment, and integrate validation through an official SDK. Do not paste the sample output into an API field expecting an encrypted license or signed proof.
Start with creating your first product and license, then use the SDK reference for your application language. All eight supported SDKs use the same licensing contracts; choosing a language does not turn random text into an issued license.
A short release checklist
- Use secure randomness and preserve the chosen format exactly.
- Keep issuance credentials and signing private keys out of shipped clients.
- Check entitlement state, context and deadlines, not just the string's shape.
- Test duplicate issuance, rejected activation and expired or modified offline proofs.
- Explain offline limits and support deadlines before the customer buys.
Build your first licensed product without building a license server.
Create a free PermitCore account, issue a test license, and validate it from your application.