How to Generate and Verify Software License Keys

How to Generate and Verify Software License Keys

When selling digital products, it’s crucial to ensure that only authorized users can access and use your software. A robust licensing system is essential to protect your intellectual property and prevent unauthorized usage.

Here’s a guide to implementing a licensing system in your software:

  1. Create an RSA public and private key pair.
  2. Use the private key to sign a message that includes the buyer’s email and software SKU.
  3. The signed message then serves as the license key, which is sent to the buyer’s email.
  4. When the buyer activates the software, verify the license key using the public key.

Let’s dive deeper into the implementation process.

Step 1: Generate a Public-Private Key Pair

To generate a public and private key pair using the RSA algorithm, you’ll need to use a command-line tool like OpenSSL.

Here’s how to do it:

  1. Open your terminal or command prompt.
  2. Run the following command:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_key.pem

This command creates a 2048-bit RSA private key and saves it as private_key.pem in the current directory. Next, we’ll use a command to derive the public key from this private key.

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

With our keys generated, let’s display them in the console for use in the next step.

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

Step 2: Create a License Key

We’ll create a basic Node.js script to generate a license key, utilizing the crypto module to sign the message with the private key and the fs module to access the private key file.

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

// Read private key from file system
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,
});

// Convert the signature to base64
const licenseKey = signature.toString('base64');

// Output the result
console.log(licenseKey);

Step 3: Verify a License Key

The license key generated in the previous step is emailed to the buyer. To verify it during activation, we can use a straightforward Node.js script that utilizes the crypto module to confirm the license key against the public key.

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

const buyerEmailAddress = '<<buyer email address>>';
const licenseKey = '<<license key>>';

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 incorporate license activation within Google Workspace add-ons, you can create a Google Cloud Function or use Google Cloud Run to manage the activation process. Your Apps Script code can send a UrlFetch POST request to this web service with the license key, receiving an activation status in return. This approach avoids the need to embed the public key directly in the script. Additionally, the user’s email address can be conveniently accessed using Session.getActiveUser().getEmail() method.

Limitations

This is a straightforward implementation of a software licensing system and doesn’t cover all potential edge cases. While it can serve as a foundation, there are additional factors to consider, such as:

  • Setting expiration dates for license keys.
  • Implementing a method to revoke license keys.
  • Preventing unauthorized key sharing among users.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *