Free code components and framework for licensing applications

Welcome to .NET Licensing, here you’ll find the information necessary to create simple and secure licenses in a .NET environment. It’s a very secure technique and easy to implement. The sample below allows you to create licenses with a customer name, company name and the number of days for a possible trial. But you can easily extend it by adding new properties.

This technique uses Microsoft’s RSA library and XML signing. The XML document contains information about the license. This document is then signed using private/public keys. After signing, the document cannot be altered. If it is, the verification method fails allowing you to invalidate the license.

Key pair generation

The code below helps generating the key pairs needed for signing the XML document. The code is minimal and requires error handling.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace DotNetLicensing
{
    public class LicenseAdmin
    {
        public string LoadKeyPairs(string file)
        {
            StreamReader stream = System.IO.File.OpenText(file);
            return stream.ReadToEnd();
        }
        public void CreateKeyPairs(string directory)
        {
            RSACryptoServiceProvider key = new RSACryptoServiceProvider(2048);

            string publicPrivateKeyXML = key.ToXmlString(true);
            string publicOnlyKeyXML = key.ToXmlString(false);

            StringToFile(directory + "_public.xml", publicOnlyKeyXML);
            StringToFile(directory + "_private.xml", publicPrivateKeyXML);
        }
        private void StringToFile(string outfile, string data)
        {
            StreamWriter outStream = System.IO.File.CreateText(outfile);
            outStream.Write(data);
            outStream.Close();
        }

    }
}

License class

With this class you can sign the XML and verify it’s signature. Verifying means checking the contents of the file it’s still in its original state.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace DotNetLicensing
{
    public class License
    {
        public bool VerifyXmlDocument(string publicKey, string licenseContent)
        {

            RSA key = RSA.Create();
            key.FromXmlString(publicKey);

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(licenseContent);
            SignedXml sxml = new SignedXml(doc);
            try
            {
                // Find signature node
                XmlNode sig = doc.GetElementsByTagName("Signature")[0];
                sxml.LoadXml((XmlElement)sig);
            }
            catch (Exception ex)
            {
                // Not signed!
                return false;
            }
            return sxml.CheckSignature(key);
        }
        public XmlDocument SignXmlDocument(string licenseContent, string privateKey)
        {
            RSA key = RSA.Create();
            key.FromXmlString(privateKey);

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(licenseContent);

            SignedXml sxml = new SignedXml(doc);
            sxml.SigningKey = key;
            sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigCanonicalizationUrl;

            // Add reference to XML data
            Reference r = new Reference("");
            r.AddTransform(new XmlDsigEnvelopedSignatureTransform(false));
            sxml.AddReference(r);

            // Build signature
            sxml.ComputeSignature();

            // Attach signature to XML Document
            XmlElement sig = sxml.GetXml();
            doc.DocumentElement.AppendChild(sig);

            return doc;
        }
    }
}

Testing application

The testing application allows you to create the key pairs and also to create license files based on the key pairs and the values provided for the document. Also the application will automatically signed the document for verification.

private void CreateLicenseButton_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(privateKey))
            {
                MessageBox.Show("Create or open a private/public key pair file");
                return;
            }
            StringBuilder licenseContent = new StringBuilder();
licenseContent.Append("<license>"); licenseContent.AppendFormat("<customer>{0}</customer>", CustomerNameText.Text);
            licenseContent.AppendFormat("<company>{0}</company>", CompanyText.Text);
            licenseContent.AppendFormat("<trial>{0}</trial>", TrialDaysText.Text);
            licenseContent.Append("</license>");

            License license = new License();

            XmlDocument fileContent = license.SignXmlDocument(licenseContent.ToString(), privateKey); StringToFile(testFolder + "testlicense.lic", fileContent.OuterXml);

            MessageBox.Show("Done");

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>