Implementing Software Licensing and Key Generation in C#

Client Application Implementation

The licensing system relies on generating a unique device token derived from hardware identifiers, which is then transformed into an activation key using a deterministic algorithm.

LicenseEngine Class

This class handles hardware fingerprinting and key derivation. It queries WMI to retrieve the CPU processor ID and the disk volume serial number, concatenates them, and extracts a substring to form a 24-character device token. The activation key is ganerated by applying a mathematical shift to each character of the device token and mapping the result into the alphanumeric ASCII range.

using System;
using System.Text;
using System.Management;

namespace AppLicensing
{
    public class LicenseEngine
    {
        public string FetchProcessorId()
        {
            string processorId = string.Empty;
            var managementClass = new ManagementClass("Win32_Processor");
            var instances = managementClass.GetInstances();
            foreach (ManagementObject instance in instances)
            {
                processorId = instance.Properties["ProcessorId"].Value.ToString();
                break;
            }
            return processorId;
        }

        public string FetchVolumeSerial()
        {
            var disk = new ManagementObject("Win32_LogicalDisk.DeviceId=\"C:\"");
            disk.Get();
            return disk.Properties["VolumeSerialNumber"].Value.ToString();
        }

        public string GenerateDeviceToken()
        {
            string rawIdentifier = FetchProcessorId() + FetchVolumeSerial();
            return rawIdentifier.Substring(0, 24);
        }

        public string DeriveActivationKey()
        {
            return DeriveActivationKey(GenerateDeviceToken());
        }

        public string DeriveActivationKey(string deviceToken)
        {
            StringBuilder keyBuilder = new StringBuilder();
            for (int i = 0; i < deviceToken.Length; i++)
            {
                int charVal = deviceToken[i];
                int shifted = (charVal * 7 + i * 3) % 128;

                if ((shifted >= 48 && shifted <= 57) || (shifted >= 65 && shifted <= 90) || (shifted >= 97 && shifted <= 122))
                {
                    keyBuilder.Append((char)shifted);
                }
                else if (shifted > 122)
                {
                    keyBuilder.Append((char)(shifted - 15));
                }
                else
                {
                    keyBuilder.Append((char)(shifted + 40));
                }
            }
            return keyBuilder.ToString();
        }
    }
}

Main Application Dashboard

Upon loading, the main form verifies the application's activation status by checking the Windows Registry. If a valid key matching the derived activation key is found, the software runs normally. Otherwise, it falls back to a trial mode, tracking usage count in the registry. Once the 30-use trial limits exceeded, the user is forced to activate the software.

using System;
using System.Windows.Forms;
using Microsoft.Win32;

namespace AppLicensing
{
    public partial class Dashboard : Form
    {
        private LicenseEngine engine = new LicenseEngine();
        private const int TrialLimit = 30;

        public Dashboard()
        {
            InitializeComponent();
        }

        private void Dashboard_Load(object sender, EventArgs e)
        {
            ValidateActivationStatus();
        }

        private void ValidateActivationStatus()
        {
            var activationKey = Registry.CurrentUser.OpenSubKey("Software\\AppLicensing\\ActivationState", true);
            string storedKey = activationKey?.GetValue("LicenseKey")?.ToString();

            if (storedKey == engine.DeriveActivationKey())
            {
                lblStatus.Text = "Software is fully activated.";
                btnActivate.Enabled = false;
                return;
            }

            lblStatus.Text = "Running in trial mode.";
            btnActivate.Enabled = true;
            
            int trialUses = 0;
            try
            {
                trialUses = (int)Registry.GetValue("HKEY_LOCAL_MACHINE\\Software\\AppLicensing", "TrialCount", 0);
            }
            catch
            {
                Registry.SetValue("HKEY_LOCAL_MACHINE\\Software\\AppLicensing", "TrialCount", 0, RegistryValueKind.DWord);
            }

            if (trialUses < TrialLimit)
            {
                trialUses++;
                Registry.SetValue("HKEY_LOCAL_MACHINE\\Software\\AppLicensing", "TrialCount", trialUses, RegistryValueKind.DWord);
                MessageBox.Show($"You have used {trialUses} of {TrialLimit} trial sessions.", "Trial Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                DialogResult result = MessageBox.Show("Trial period expired. Would you like to activate?", "Activation Required", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (result == DialogResult.Yes)
                {
                    OpenActivationDialog();
                }
                else
                {
                    Application.Exit();
                }
            }
        }

        private void btnActivate_Click(object sender, EventArgs e)
        {
            OpenActivationDialog();
        }

        private void OpenActivationDialog()
        {
            using (ActivationDialog dialog = new ActivationDialog())
            {
                dialog.ShowDialog();
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

Activation Dialog

This dialog prompts the user to input an activation key. It displays the local device token for the user to send to the vendor. Upon submission, it compares the entered key against the expected derived key. If they match, the key is persisted to the registry to unlock the application.

using System;
using System.Windows.Forms;
using Microsoft.Win32;

namespace AppLicensing
{
    public partial class ActivationDialog : Form
    {
        private LicenseEngine engine = new LicenseEngine();

        public ActivationDialog()
        {
            InitializeComponent();
        }

        private void ActivationDialog_Load(object sender, EventArgs e)
        {
            txtDeviceToken.Text = engine.GenerateDeviceToken();
        }

        private void btnSubmit_Click(object sender, EventArgs e)
        {
            string inputKey = txtActivationKey.Text.Trim();
            string expectedKey = engine.DeriveActivationKey();

            if (inputKey == expectedKey)
            {
                MessageBox.Show("Activation successful! Please restart the application.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
                var regKey = Registry.CurrentUser.CreateSubKey("Software\\AppLicensing\\ActivationState");
                regKey.SetValue("LicenseKey", inputKey);
                regKey.SetValue("RegisteredUser", "ActiveUser");
                this.Close();
            }
            else
            {
                MessageBox.Show("Invalid activation key provided.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txtActivationKey.SelectAll();
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

Key Generator Implementation

The key generator is a separate utility used by vendors to create valid activation keys from device tokens supplied by users. It implements the identical derivation algorithm but accepts the device token as an input parameter rather than reading local hardware data.

KeyGenEngine Class

using System;
using System.Text;

namespace KeyGenUtility
{
    public class KeyGenEngine
    {
        public string GenerateKeyFromToken(string deviceToken)
        {
            StringBuilder keyBuilder = new StringBuilder();
            for (int i = 0; i < deviceToken.Length; i++)
            {
                int charVal = deviceToken[i];
                int shifted = (charVal * 7 + i * 3) % 128;

                if ((shifted >= 48 && shifted <= 57) || (shifted >= 65 && shifted <= 90) || (shifted >= 97 && shifted <= 122))
                {
                    keyBuilder.Append((char)shifted);
                }
                else if (shifted > 122)
                {
                    keyBuilder.Append((char)(shifted - 15));
                }
                else
                {
                    keyBuilder.Append((char)(shifted + 40));
                }
            }
            return keyBuilder.ToString();
        }
    }
}

Key Generator Window

using System;
using System.Windows.Forms;

namespace KeyGenUtility
{
    public partial class KeyGenWindow : Form
    {
        private KeyGenEngine engine = new KeyGenEngine();

        public KeyGenWindow()
        {
            InitializeComponent();
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            try
            {
                string token = txtDeviceToken.Text.Trim();
                if (string.IsNullOrEmpty(token))
                {
                    MessageBox.Show("Please enter a device token.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                string activationKey = engine.GenerateKeyFromToken(token);
                txtActivationKey.Text = activationKey;
            }
            catch (Exception)
            {
                MessageBox.Show("Invalid token format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

Tags: C# WMI Windows Registry Software Licensing Keygen

Posted on Tue, 11 Aug 2026 16:37:04 +0000 by love_php