How to generate software license keys and verify them

Learn how to generate software license keys and verify them using the Crypto API. Keys can be activated offline and do not require a database.

You’re running a small software business that sells digital downloads — apps, plugins, or even templates. When the buyer completes the purchase, you need to provide them with a license key that they can use to activate and validate the software.

Here’s how you can apply such a licensing system to your software:

  1. Generate a public and private key pair using the RSA algorithm.
  2. Sign the message with the private key. The message includes the buyer’s email address and software SKU.
  3. A signed message is the license key that is sent back to the purchaser’s email address.
  4. When the purchaser activates the software, the license key is verified using the public key.

Advantages

The advantage here is that the public key can be included in the source code of the software, there is no need to use a database, and the buyer can verify the license key offline without needing to connect to your server.

Now let’s go through the implementation steps in detail.

1. Generate a public and private key pair

We will generate a public and private key pair using the RSA algorithm. Start a terminal and run the following openssl command.

openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_key.pem

It will generate a 2048-bit RSA private key and save it to a file private_key.pem In the current folder. Next, we will write a command to generate a public key from a private key.

openssl rsa -pubout -in private_key.pem -out public_key.pem

Now that we have our keys, let’s print them to the console as we will need them in the next step.

openssl pkey -in private_key.pem && openssl pkey -pubin -in public_key.pem

2. Generate a license key

We will write a simple Node.js script to generate the license key. It uses crypto Module to sign messages with private key and fs A module for reading a private key from a file system.

const crypto = require('crypto');
const fs = require('fs');


const privateKey = fs.readFileSync('private_key.pem', 'utf8');

const buyerEmailAddress = 'amit@labnol.org';
const data = Buffer.from(buyerEmailAddress);

const signature = crypto.sign('sha256', data, {
  key: privateKey,
  padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
});


const licenseKey = signature.toString('base64');


console.log(licenseKey);

3. Verify the license key

The license key generated in the previous step is sent to the buyer’s email address and we need to verify it when the buyer activates the software.

This is again a simple Node.js script that uses crypto Module to verify license key with public key.

const crypto = require('crypto');
const fs = require('fs');

const buyerEmailAddress = '<>';
const licenseKey = '<>';

const publicKey = fs.readFileSync('public_key.pem', 'utf8');
const signatureBuffer = Buffer.from(licenseKey, 'base64');

const licenseStatus = crypto.verify(
  'sha256',
  Buffer.from(buyerEmailAddress),
  {
    key: Buffer.from(publicKey),
    padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
  },
  signatureBuffer
);

console.log(licenseStatus ? 'Activated' : 'Invalid license key');

License Activation in Google Apps Script

If you plan to include activation in Google Workspace add-ons, you can build a Google Cloud Function or Google Cloud Run service to handle license activation.

Your apps script code can make a UrlFetch POST request to the web service with the license key and get back the activation status. In such cases, the public key does not need to be embedded in the script. Also, the user’s email address can be easily retrieved using Session.getActiveUser().getEmail() method.

boundaries

This is obviously a basic implementation of a software licensing system that does not handle all edge cases. This can be a starting point but there are many other things to consider:

  • How to set expiration dates for license keys.
  • How to revoke a license key.
  • How to prevent key sharing between users.

Leave a Comment