Thursday, January 26, 2006

In my previous post I showed you the class diagram and the usage for the Licensing classes that are available as a part of SDF v2.

Today I'll explain a few other steps that you will be required to do in order to have licensing enabled in your application.

Attentive readers had probably noticed from looking at the class diagram that I have provided implementation of a concrete class PublicKeyLicenseProvider that inherits from the abstract LicenseProvider. The internal implementation of the PublicKeyLicenseProvider class is based on the asymmetric encryption such as RSACryptoServiceProvider. This was made possible by the fact that Microsoft has provided the implementation of the System.Security.Cryptography namespace to the CF v2.

Little bit of the background information on the asymmetric encryption. Asymmetric Encryption is a form of encryption where keys come in pairs. What one encrypts, only the other can decrypt. Asymmetric Encryption is also known as Public Key Cryptography, since users typically create a matching key pair, and make one public while keeping the other secret.

This fact has brought me to the idea of possibility to implement an almost fool proof system for licensing of components and applications in the CF v2. Even considering an "openness" of the .NET assemblies through the tools like Reflector, as long as your private key will stay unknown to a possible hacker, they will have a little chance to break the encryption.

And now after you have digested this information, you should be able to understand the other steps that are required:

1. You will have to generate a pair of the Public and Private keys. I have created a class LicenseKeyGenerator to help you with this task. Here's the CreateKeyPair method that you can use on either Windows CE or a desktop to generate these keys:

public static void CreateKeyPair( string path, int keySize )

{

      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider( keySize );

      // Open the file stream for writing of the public key

      FileStream keyWriter = new FileStream(Path.Combine(path, "Pub.key"), FileMode.Create);

      // Get the key from provider

      byte[] key1 = rsa.ExportCspBlob(false);

      //Write it to the file

      keyWriter.Write(key1, 0, key1.Length);

      keyWriter.Close();

 

      // Open the file stream for writing of the private key

      keyWriter = new FileStream(Path.Combine(path, "Priv.key"), FileMode.Create);

      // Get the key from provider

      byte[] key2 = rsa.ExportCspBlob(true);

      //Write it to the file

      keyWriter.Write(key2, 0, key2.Length);

      keyWriter.Close();

}

2. Add the generated public key file Pub.key to the root (this is very important) of your project and set its Build Action to the Embedded Resource.

3. Add the LicenseProviderAttribute to your component as I had already shown to you in the previouse post.

4. Generate the license file based on the user data. The license is a simple XML file in the following format:

<licenseKey version="1.0">

    <product version="1.0.3.2489">NewControlproduct>

    <customerInfo>

        <Name>John DoeName>

        <Email>john.doe@mail.comEmail>

    customerInfo>

    <key>f4/WgB2JhgR9bQibFa6rbGDugM+4wqbyM/ES+6W17gxx+x//G9at5he3yT0wZGwk2okSAzqrRJoNfsakEDMlFg==key>

licenseKey>

 

The value of the key tag is the public key that we have generated in the previouse step. Here is the method Generate from the LicenseKeyGenerator class:

public void Generate(string publicKeyFile, string licenseFile)

{

      //Open public key file

      FileStream fs = new FileStream(licenseFile, FileMode.Open);

      BinaryReader keyReader = new BinaryReader(fs);

      // Create encryptor

      RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();

      rsaProvider.ImportCspBlob(keyReader.ReadBytes((int)keyReader.BaseStream.Length));

 

      // sign and save.

      this.Sign(rsaProvider);

      this.Save(licenseFile);

}

And you will use it like so:

private void cmdGenerate_Click(object sender, EventArgs e)

{

       // Create new license key.

       LicenseKeyGenerator licenseKey = new LicenseKeyGenerator();

       licenseKey.ProductName = txtProduct.Text;

       licenseKey.ProductVersion = txtVersion.Text;

       licenseKey.CustomerName = txtCustName.Text;

       licenseKey.CustomerEmail = txtCustEmail.Text;

 

       licenseKey.Generate((Application.ExecutablePath) + @"\Keys\Priv.Key", "MyCompany.NewControl.lic");

}

You can download the full version for the LicenseKeyGenerator class and a sample project from here:

GenLicense.zip (23.81 KB)

After you are done with these steps, the result is simple and effective - you've got a licensing system in place that would be rather hard to brake and easy to use.

1/26/2006 1:52:45 PM (GMT Standard Time, UTC+00:00)  #     |