Wednesday, February 8, 2023

Open source .NET software license manager


DGLicenseLib is  .NET library you can use in your project to manage software licenses.

If you distribute your software and need a way to give your customer a personalized license number, this library can help you.

It's open source, and available as a package on nuget.

This library uses asymmetric cryptography to sign a license key. The license key is the verified by the client software to allow software usage.

DGLicenseLib uses an Elliptic Curve Digital Signature Algorithm (https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) to sign the license, namely the secp256k1.

It's composed by three parts:

  • DGLicenseLib: the main license library that implements sign and verify function, it can also be used to generate new key pairs
  • DGLicenseLibDeviceId: this library it's used to generate "unique" id based on the PC hardware running the software
  • DGLicenseLibUC: this library contains a couple of UI helper that can be integrated in the client software to simplify the licensing
  • DGLicenseLibManager: this is the GUI application that helps you to manage your distribuited license

The idea behind this library is that you can develop your own interface, GUI, CLI, API... but there are a couple already deployed. This will save you time. So, all the function exposed above can be implemented by directly calling the DGLicenseLib, for the sake os semplicity I'll explain you by using the UI provided by the software.

First, you have to generate a license keypair using the application DGLicenseLibManager. Just give a name to your keypair, and click Generate. This will pack your keypair (private + public key) in one single file.


On client side, you have to include in your software the provided public key.

Another thing you can do, if you want to restrict your license to a PC, is generating an unique id for the PC which is running the software. This can be done in several way, the helper provided by the library DGLicenseLibDeviceId do this for you just by calling the method GetDeviceId.

This method will generate an unique device Id based one your hardware: 

  • Motherboard Serial Number
  • CPU identifier

Now just set a filename for your license file.

If you use the helper included in the DGLicenseLibUC library, you just can check you license by calling the method CheckLicenseFile.

This method will do the following for you:

  • load license from your license file (if one exists)
  • show a license helper UI that ask the user to fill a license key to activate the software

Of course you can set a null device id. This way the license provided can run on all the PC.

In just a few line of code you have secured your software, find an example below

string licensePublicKey = "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEKKAzjD8Ln5dJagBqIVWImHJH4R4VTQ9A\nfSbdjk7B7pcwZFiBP6xCV7A4fpN1C7YmgtfJ5WdO+Sjwxq1S8pwM/A==\n-----END PUBLIC KEY-----";
string licenseDeviceId = DGLicenseLibDeviceId.GetDeviceId();
string licenseFilename = "license.lic";
Nullable<DGLicenseLib.License> license = null;
if (!DGLicenseLibClientHelper.CheckLicenseFile(licensePublicKey, licenseDeviceId, licenseFilename, out license))
   this.Close();

The user now has to request a license by sending you the license request. Which is the Base64 encoded value of  the public key and your device id.

You can now use the DGLicenseLibManager application to Sign a new license. When signing the license you can

  • set an expire date, if non is selected the license will not expire
  • set additional data

The license payload:

  • device id
  • expire date
  • additional data

is then signed and the payload and his sign are encoded in Base64 format.

This is the string you can give your customer.

The user now can insert this license key. The provided helper will check the key validity by using the public key of the software. It will also check for the device id provided and the expire date. If check passes the license file is written.

Next time the softare restar the license file will pass the check and the license form will now shows up.

Code is distributed with a sample client project "DGLicenseLibClientSample" you can take a look at.

The UI helper for client is also internationalizable by using json files or an extenal class loaded. Find and example in the sample client project.

Asymmetric signing code embedded in this project is taken from the library "A lightweight and fast ECDSA implementation" (https://github.com/starkbank/ecdsa-dotnet).

The device id generation code is indeed taken from the library "DeviceId" (https://github.com/MatthewKing/DeviceId).

You can consider this library as an helper package to develop you licensing solution for your software. But this will not have to give you a false sense of security. Indeed anything that is distributed as an application can be cracked. You can obfuscate and pack your software with open source or commercial software and libraries but an expert hacker can crack your system. You'd rather focus on making your customer happy, this will give you a change that your customer will not crack your software but pay you for that. And this library will help you developing a license solution with just a few lines.


Code, Binary & Packages


Notes
  • read risk disclaimer
  • excuse my bad english

No comments:

Post a Comment