Miqo.License provides you with all the neccessary tools to issue, sign and verify the authenticity of a license. License files are digitally signed using a state-of-the-art Elliptic Curve Digital Signature Algorithm (ECDSA) to ensure that the licenses cannot be tampered with after creation.
The library is available for .NET Standard 2.0 and .NET Framework 4.0 and higher. The tests project uses .NET Core 2.0. Both the library and the NuGet package are signed.
The Miqo.License library makes it easy to:
- Securely create, sign and validate your licenses.
- Support various license types/models including trial, standard, personal, etc.
- Enable/disable product features.
- Add additional attributes to the license as needed.
- Save as a JSON file or to a JSON formatted string.
The library is available as a signed NuGet package.
PM> Install-Package Miqo.License
Before signing a license file, you'll need a private and public key. Miqo.License uses an Elliptic Curve Digital Signature Algorithm (ECDSA) to ensure that the license files can't be tampered with after creation. The private key is used to sign the license file, and the public key is used to verify the authenticity of the license.
You can use the bundled Key Creation Tool or create a
new pair using Signer()
like this:
var signer = new Miqo.License.ECC.Signer();
var privateKey = signer.PrivateKey;
var publicKey = signer.PublicKey;
Use Signer(privateKeyString)
to provide a previously generated private
key.
The private key should be stored securely and should be unique for each of your products. The public key is distributed with your software. If you want your customer to buy a new license on each major release you can create a key pair for each release and product.
After generating the key pairs for your product you are ready to create a new license. The easiest way to do this is to use the FluentLicense class.
var license = FluentLicense.CreateLicense()
.WithUniqueIdentifier(Guid.NewGuid())
.As(LicenseType.Standard)
.ExpiresAt(DateTime.Today.AddYears(1))
.ForProduct("Chewing Gum")
.LicensedTo(new Customer {
Name = @"Angus 'Mac' MacGyver",
Email = "[email protected]",
Company = "Phoenix Foundation"
})
.SignLicenseWithPrivateKey(privateKey);
The license is now signed and you are ready to save it as a JSON file:
license.Save("ChewingGum.License");
If you would like to store the license file in a database or other fashion, you can use:
var jsonString = license.ToJsonString();
Load the license from a file:
var license = License.Load("ChewingGum.License");
You can also load a license from a string:
var license = License.LoadFromString(jsonString);
You can now start validating the license:
using Miqo.License.Validation;
var validationFailures = license.Validate()
.ProductName("Chewing Gum")
.And()
.ExpirationDate()
.And()
.Signature(publicKey)
.AssertValidLicense();
Miqo.License will not throw any exceptions when a validation fails, but will rather return an enumeration of validation failures.
Simply check if there is any failure:
if (validationFailures.Any()) {
...
Or if you would like to iterate over each failure use:
foreach (var failure in validationFailures) {
Console.WriteLine($"{failure.GetType().Name}: {failure.Message} - {failure.HowToResolve}");
}
Use validationFailures.ToList();
before attempting to use the result
multiple times.
Note that Miqo.License uses byte[]
for the private and public keys. You
can use the HexExtensions
extension class to quickly convert between
the byte[]
and hex string
.
byte[] publicKey = ECC.HexExtensions.ToHex(publicKeyHexString);
string hex = ECC.HexExtensions.HexToBytes(publicKey)
The license file is saved in standard JSON format.
{
"license": {
"id": "39bca166-e7ad-471a-955c-873673a9115d",
"createdAt": "2018-07-24T19:36:57.1917491Z",
"product": "Chewing Gum",
"licenseType": "Standard",
"customer": {
"name": "Angus 'Mac' MacGyver",
"company": "Phoenix Foundation",
"email": "[email protected]"
},
"expiresAt": "2019-07-24T00:00:00+02:00"
},
"signature": "ee9wYUeADZUlP7+Q+3PdrtBXqb4ricPlebTBbkMmYEdsPt/D3f6vVwlKQ4jrN1pGECaCTmljMOWWfDUNknLGdA=="
}
You can use the bundled Key Creation Tool to quickly generate a new key pair in hex string format.
Miqo.License was inspired by Portable.Licensing (by Daniel Nauck, Nauck IT) and uses some of the validation code.
Two other libraries are also used for the ECDSA part.
- Signing is done using Cryptography.ECDSA (by Chainers)
- Signature verification is done using ChainEngine.Cryptography.EcDsa.Secp256k1 (by UChainDb)
Miqo.License is made available under the MIT License.