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:
- Create an RSA public and private key pair.
- Use the private key to sign a message that includes the buyer’s email and software SKU.
- The signed message then serves as the license key, which is sent to the buyer’s email.
- 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:
- Open your terminal or command prompt.
- 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.