Click here to Skip to main content
15,350,416 members
Articles / Programming Languages / C#
Technical Blog
Posted 8 Dec 2016

Tagged as

Stats

9.7K views
23 bookmarked

Using SSH Keys for License Generation and Validation in .NET Applications

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
8 Dec 2016CPOL3 min read
How to implement license functionality in your .NET application

license_generationpng

This blog post is going to present how you can implement license functionality in your .NET application. Providing license in your .NET application is very challenging because there is no standard procedure for the implementation. You are free to use whatever you want. But notice, there is no license which is 100% safe and cannot be cracked or bypassed.

For this purpose, I have selected the CocoaFob library for registration code generation and verification in Objective-C applications. Mainly, the library is for Objective -C based applications, like iQS mobile applications and other OSX based applications. This is a very interesting library but you cannot use it in .NET applications, there is no implementation for .NET Framework.

The library uses DSA to generate registration keys, which is very hard for hackers to produce key generators. The library is also specific because it generates license key in human readable form, when the bytes are converted into Base32 string to avoid ambiguous characters. It also groups codes in sets of five characters separated by dashes. Also DSA has encryption algorithm that generates the license which is different every time because of a random element introduced during the process.

So the License key is produced using a 512-bit DSA key that looks like the following sample:

GAWQE-FCUGU-7Z5JE-WEVRA-PSGEQ-Y25KX-9ZJQQ-GJTQC-CUAJL-ATBR9-WV887-8KAJM-QK7DT-EZHXJ-CR99C-A

More information about CocoaFob can be found at GitHub page: https://github.com/glebd/cocoafob

The library uses BouncyCastle.Crypto Nuget package for DSA encryption and decryption.

The library CocoaFob for .NET contains two classes:

  1. LicenseData class which provides License properties which are used in license generation. It can be anything: Name, Product number, email, date of expiration, etc.
  2. LicenseGenerator class which is responsible for encrypting and validating the license.

For this blog post, the License data class has the following implementation:

C#
public class LicenseData
{
protected internal string productCode;
protected internal string name;
protected internal string email;

public virtual string toLicenseStringData()
{
 StringBuilder result = new StringBuilder();
 if (productCode != null)
 {
 result.Append(productCode);
 result.Append(',');
 }

 //name is mandatory property
 if (name == null)
 throw new System.Exception("name cannot be null");
 result.Append(name);

 if (email != null)
 {
 result.Append(',');
 result.Append(email);
 }
 return result.ToString();
}
......
}

As can be seen from the code snippet above, the License data contains username, product key and email address. Also, only name property is mandatory, which means you can generate license key based on the user name only.

Generating the License Key

Once we have License data, we can process License key generation. License is generated using DSA encryption which uses SSH private key. You can generate public and private SSH keys using any of the available tools, e.g., OpenSSH, GitHub bash, …. You can find more information about private and public key generation at this link. Once we have public and private keys, we can generate license and validate it. One important thing to remember is that you have to care about your private key. It should always be secure and no one should have access to it.

The public key is used for license validation, and it is usually packed with the application as a part of the deployment stuff. So the process of generating the license is shown on the following code snippet:

C#
public string makeLicense(LicenseData licenseData)
{
     if (!CanMakeLicenses)
     {
       throw new System.InvalidOperationException
         ("The LicenseGenerator cannot make licenses as it was not configured with a private key");
     }
     try
     {
        //
        var dsa = SignerUtilities.GetSigner("SHA1withDSA");
        dsa.Init(true, privateKey);
        //
        string stringData = licenseData.toLicenseStringData();
        byte[] licBytes = Encoding.UTF8.GetBytes(stringData);
        dsa.BlockUpdate(licBytes, 0, licBytes.Length);
        //
        byte[] signed = dsa.GenerateSignature();
        string license = ToLicenseKey(signed);
        return license;
    }
    catch (Exception e)
    {
        throw new LicenseGeneratorException(e);
    }
}

First, the DSA encryption is created based on the publicKey we have provided as an argument. Then licBytes is generated from the License data, and converted in to UTF8 formatted bytes. Then, we have update DSA provider with licBytes. Now the DSA provider can generate signature in bytes. The signature is converted into LicenseKey by calling ToLicenseKey method. The method is shown on the following code snippet:

C#
private string ToLicenseKey(byte[] signature)
{
    /* base 32 encode the signature */
    var result = Base32.ToString(signature);

    /* replace O with 8 and I with 9 */
    result = result.Replace("O", "8").Replace("I", "9");

    /* remove padding if any. */
    result = result.Replace("=", "");
           

    /* chunk with dashes */
    result = split(result, 5);
    return result;
}

The magic happens in this method during the conversion of signature from bytes to human readable string. Conversion is done using Base32 string helper method.

Verify the License Key

The License verification process is defined in verifyLicense method. You have to provide SSH publicKey as well as:

C#
public virtual bool verifyLicense(LicenseData licenseData, string license)
{
	if (!CanVerifyLicenses)
	{
		throw new System.InvalidOperationException
		("The LicenseGenerator cannot verify licenses as it was not configured with a public key");
	}
    try
     {
        //Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
        var dsa = SignerUtilities.GetSigner("SHA1withDSA");
        dsa.Init(false, publicKey);

        //
        string stringData = licenseData.toLicenseStringData();
        byte[] msgBytes = Encoding.UTF8.GetBytes(stringData);
        dsa.BlockUpdate(msgBytes, 0, msgBytes.Length);


        var dec = FromLicenseKey(license);
        var retVal = dsa.VerifySignature(dec);
        //
        return retVal; 
	}
    catch (Exception e)
    {
        throw new LicenseGeneratorException(e);
    }
}

As can be seen from the code above, the validation process is done by generating licenseData, converting the license Key into signature and the validation process returns true if the license is valid, otherwise it returns false.

The whole project is published at Github, and can be downloaded from http://github.com/bhrnjica/cocoafob.

Testing the Library

The Library solution contains a unit test project in which you can see how to use this library in the real scenario in order to implement licensing in .NET app.

Happy programming!

Filed under: .NET, CodeProject, Windows
Tagged: .NET, C#, Code Project, CodeProject, DSA Encryption, License Key
Image 2 Image 3

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bahrudin Hrnjica
Software Developer (Senior)
Bosnia and Herzegovina Bosnia and Herzegovina
Bahrudin Hrnjica holds a Ph.D. degree in Technical Science/Engineering from University in Bihać.
Besides teaching at University, he is in the software industry for more than two decades, focusing on development technologies e.g. .NET, Visual Studio, Desktop/Web/Cloud solutions.

He works on the development and application of different ML algorithms. In the development of ML-oriented solutions and modeling, he has more than 10 years of experience. His field of interest is also the development of predictive models with the ML.NET and Keras, but also actively develop two ML-based .NET open source projects: GPdotNET-genetic programming tool and ANNdotNET - deep learning tool on .NET platform. He works in multidisciplinary teams with the mission of optimizing and selecting the ML algorithms to build ML models.

He is the author of several books, and many online articles, writes a blog at http://bhrnjica.net, regularly holds lectures at local and regional conferences, User groups and Code Camp gatherings, and is also the founder of the Bihac Developer Meetup Group. Microsoft recognizes his work and awarded him with the prestigious Microsoft MVP title for the first time in 2011, which he still holds today.

Comments and Discussions

 
QuestionQuestion Pin
Abbathsin7-Aug-19 16:48
MemberAbbathsin7-Aug-19 16:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.