Tag: software licensing

Offline SDK protection in .NET with software licensing

A common way to distribute functionality is by creating an SDK that can be consumed by developers inside their own application. The advantage of shipping functionality as an SDK is that you can focus on improving the core algorithms without the need of creating a separate GUI for a specific use-case.

Cryptolens already offers a way to protect SDKs and today we would like to introduce a new way that was specifically developed for .NET libraries that are permanently offline or where a perpetual licensing model is preferred.

How it works

The idea behind the new SDK licensing technique is to require developers to sign the application that will use your SDK with a special utility. When this is done, a new file with the certificate will be created in the same folder, which can later be verified when the SDK is called. This ensures that only authorised developers can develop applications that use your SDK.

Inside the SDK, you only need to call Helpers.VerifySDKLicenseCertificate() with your RSA public key, and it will make sure that the certificate is valid. A nice feature of this method is that it also returns a LicenseKey object, which you can use to decide which features should be available, etc. You can see a demo of this here.

In order to sign an assembly, developers can use a special utility that is available open-source on GitHub. Developers need to provide their license key and the assembly signing utility will automatically send their machine code so that you can control which developer machines can perform the signing operation.

Getting started

To get started, please check out the tutorial for SDK developers on the following page. All the helper tools and demo projects are available open-source in our GitHub repo.

Sign up customers automatically for the customer portal

A recent addition to the platform is the ability to sign up customers automatically to the customer portal. Instead of creating a customer manually or through the API, you can publish a generic link that will automatically register a customer with your account. This link can be found on the customer page.

In addition to allowing your customers to see their current licenses, the customer portal gives them the option to order new licenses as well as use their login credentials instead of the license key when unlocking your software. We will cover each case below.

Why customer portal?

Listing licenses

When you assign licenses to a customer account, your customers will be able to see all their licenses and their properties, such as the set of features they are entitled to and when they expire.

Recurring payments

If you have set up Stripe with your account, you can allow your customers to sign up for a plan in the customer portal and get instant access to a valid license key. They can also easily manage their subscriptions. You can read more about how you can get started here.

User account authentication

Instead of using a license key, you can allow your customers to authenticate using their login credentials. Cryptolens has developed a state-of-the-art protocol that preserves the privacy of your customers (more information about the protocol can be found here). You can read more on how to get started here.

Managing app settings in software licensing

When developing apps, you will likely need to store some metadata. This can either be specific to a certain user or be shared among all users.

Data objects offer an easy way of managing metadata either on the product, license key or machine code level. They are quite useful since it’s easy to change them as your application evolves and user-specific data will stay the same across all devices.

In this article, we will cover data objects associated with a product.

Editing metadata

To add or edit data objects on the product level, you can click on the Data Objects link as shown below:

On the next page, you can either add or edit existing data objects. The names are case-sensitive and duplicates are not allowed.

Retrieving metadata on app start

Let’s assume our application needs to obtain the currently supported DOTNET_RUNTIME (which we defined in the previous step). This can be accomplished with the code below (the project files are available here).

To get it up and running, we need to specify an access token and modify the ReferencerId. The access token needs to have the “ListDataObjects” permission checked and we also strongly recommend to specify the product it should work with. The ReferencerId should be the Id of the product.

 var systemSettings = Data.ListDataObjects("access token", new ListDataObjectsModel
 {
     ReferencerType = DataObjectType.Product,
     ReferencerId = 3349,  // <- the product id
 });
 
 if(!Helpers.IsSuccessful(systemSettings) || systemSettings.DataObjects == null)
 {
     Console.WriteLine("Could not retrieve the settings.");
 }

 var settings = systemSettings.DataObjects.ToDictionary(x=> x.Name, x => x);

 if(settings.ContainsKey("DOTNET_RUNTIME"))
     Console.WriteLine(settings["DOTNET_RUNTIME"].StringValue);

What’s next?

In the future tutorials we will describe how you can store user specific information. In meantime, let us know if you have any questions πŸ‘

Autodesk Maya plugin software licensing

In the beginning of the year, we looked at licensing for Autodesk AutoCAD. Today, we are announcing support for another Autodesk product, Maya. Similar to AutoCAD, Maya allows you to develop plug-ins, and in this post we are going to cover how licensing works if you plan to sell them.

Adding software licensing library

Maya supports Python 2 for plugin development. To add license verification, only two things are necessary:

  1. Download and place cryptolens_python2.py into your plugin folder.
  2. Add the correct namespaces and the key verification logic, as described here.

If you want to read more about plug-in development in Maya, please check out this tutorial.

The next step is to sell your plugin, which we covered in the AutoCAD article. As always, let us know if you have any questions πŸ™‚

Data collection for better insights in software licensing

By default, Cryptolens logs most of the requests made to the Web API. This information can give some basic insights into how the application is being used. In the latest release of the platform, we have expanded the list of methods that are being logged.

However, API logs don’t capture all events that could be useful from an analytics standpoint. For example, it won’t tell you the most popular feature, OS or answer questions such as which OS brings in most revenues. As a solution, we have released a new API method that allows you submit additional data, in .NET referred to as AI.RegisterEvent (you can also call the RegisterEvent Web API method directly).

The idea is that this method is called in two ways: inside the app (to track when a certain feature is used) and on the backend (upon a successful transaction.

Inside the app, it can be called as shown below:

AI.RegisterEvent("access token with RegisterEvent permission", 
    new RegisterEventModel { EventName = "start", FeatureName = "YearReportGenerator", Key= "AAAA-BBBB-CCCC-DDDD", MachineCode = Helpers.GetMachineCode(), ProductId = 3,
    Metadata = Helpers.GetOSStats() });

When a transaction has occurred, we can send a GET request to the url below. The only difference is that we have provided a “value” and a “currency”.

https://app.cryptolens.io/api/ai/RegisterEvent?token=<access token with RegisterEvent permission>&Value=30&Currency=USD&ProductId=3&MachineCode=<machine code>

The complete tutorial is available here. As always, let us know if you have any questions πŸ™‚

License templates for frequently used license configurations

To make it easier to create licenses of a common type, we have introduced a new feature called license template. In short, it’s a way to save license configurations (eg. features, set time, maximum number of machines) so that they can be re-used later.

It’s quite easy to get started. To save a license configuration, you can click on Save as Template button on the key creation page. This will re-direct you to a new page where you can provide a name for that configuration. Next time you want to generate a license from this configuration you can select it in the drop down list and click on Create button next to it.

We are always happy to hear your feedback or help you in case you have any questions πŸ™‚

Support for any number of features

A common request we have received from our customers is to support more than 8 features. Until now, the recommended approach has been to use the notes field or data object fields to store any additional feature information. With this update, the dashboard and several of our clients have built in support for additional features.

In addition to being able to define any number of features, we have also made it possible to define feature hierarchies. For example, we can define the following feature hierarchy:

Now, suppose the user opens ModuleB. With the above setup, we can either check if they have permission to use ModuleB or we can be more specific and require Submodule 1 to be present.

We will go through in more detail how you can get started later in the article. The feature template used for our above example is shown below:

["ModuleA", ["ModuleB", ["Submodule 1", "Submodule 2"]], "ModuleC", ["ModuleD", ["ModuleD1", ["Submodule D1", "Submodule D2"]]]]

Set up

Defining features

Let’s suppose we want to define the following feature hierarchy:

To define it, we can use a JSON array structure shown below:

["ModuleA", "ModuleB", "ModuleC"]

Suppose now that we want to add sub features to ModuleB. For example, Submodule 1 and Submodule 2. To do that, we introduce a new array instead of the string “Module B”, which has the following structure:

["Module B", ["Submodule 1", "Submodule 2"]]

The first element defines name of the module, and the second element should ways be a list of submodules.

We can keep adding submodules to submodules in a similar fashion.

To add your feature template to a product, you can click on Edit Feature Names on the product page and then scroll down until you see Feature Template.

In the example above, we would get the following feature hierarchy

It’s defined with the following feature template

["ModuleA", ["ModuleB", ["Submodule 1", "Submodule 2"]], "ModuleC"]

Assigning features

Once you have defined the feature template, the page to create a new license key and to edit existing one will have a box that allows you to define them, as shown below. The state will be stored in a data object with the name cryptolens_features, which we will cover in the next step.

Verifying features

At the time of writing, the Java client supports checking these additional features out of the box. You can do that using a special version of Helpers.HasFeature() method. For example, to check if Submodule1 is present, you can type

Helpers.HasFeature(license, "ModuleB.Submodule 1")

If you only want to check if ModuleB is present, without being specific, you can insteadwrite

Helpers.HasFeature(license, "ModuleB")

Plan ahead

Support for additional features is a fairly new feature so we would be grateful if you could report any errors or suggestions to us. At the time of writing, the Java client supports this out of the box. We plan to ship this to our other client libraries, starting with .NET. If you would like us to focus on a specific client library, please let us know.

As always, let us know if you have any questions πŸ™‚

Analytics of feature usage

Cryptolens offers different ways to analyse usage data. The standard analytics portal uses information generated when licenses are verified, which allows you to get insights where your users are located, when they use the application, etc.

There also an option to send in more data, which will give better insights about how different modules are used. We will cover this in this post.

Sending in data

To register an event, you can call the RegisterEvent method. Most of the parameters are optional, but it’s useful to at least supply a FeatureName and either Key or MachineCode. If you just have one product, ProductId is not necessary, but it’s useful if you have multiple products.

Cryptolens always needs to be able to link usage data to a unique user to give better results. The code snippet below can be used to register event, in our case that the user started YearReportGenerator module.

AI.RegisterEvent("access token with RegisterEvent permission", 
    new RegisterEventModel { EventName = "start", FeatureName = "YearReportGenerator", Key= "AAAA-BBBB-CCCC-DDDD", MachineCode = Helpers.GetMachineCode(), ProductId = 3 });

If you are using any other environment, the same can be accomplished with with a GET request as follows:

https://app.cryptolens.io/api/ai/RegisterEvent?token=<access token with RegisterEvent permission>&Value=30&Currency=USD&ProductId=3&MachineCode=<machine code>

More details about what information can be sent is available here.

Retrieving data

If you would like to analyse the data yourself, you can use GetEvents method to retrieve it. However, it’s also possible to get visual representation on the this page. The GUI is continuously improved, so if you have any feedback, you are more than welcome to get in touch. Below are several screenshots. The first image shows the summary of all the features:

The second image below shows event distribution:

Node.js software licensing

Today we have released a client library for Node.js, which can be installed quite easily using the command below:

npm install cryptolens

Once it’s installed, you can verify a license key using the code below:

const Key = require('cryptolens').Key;

var RSAPubKey = "{Your RSA Public key, which can be found here: https://app.cryptolens.io/User/Security}";
var result = Key.Activate(token="{Access token with with Activate permission}", RSAPubKey, ProductId=3349, Key="GEBNC-WZZJD-VJIHG-GCMVD", MachineCode="test");

result.then(function(license) {
    if (!license) {
        // failure
        return;
    }
    
    // Please see https://app.cryptolens.io/docs/api/v3/model/LicenseKey for a complete list of parameters.
    console.log(license.Created);
});

If you want to load a license key (eg. for offline activation), you can use LoadFromString method available in the Helpers namespace. You can read more about it here.

Disclaimer: this is not an April joke, we support Node.js for real πŸ™‚

Golang software licensing

Today, we have released a library for Golang, freely available on GitHub. It supports both key verification and offline verification. To verify a license key, the code below can be used:

token := "Access token"
publicKey := "RSA Public key"

licenseKey, err := cryptolens.KeyActivate(token, cryptolens.KeyActivateArguments{
	ProductId:   3646,
	Key:         "MPDWY-PQAOW-FKSCH-SGAAU",
	MachineCode: "289jf2afs3",
})
if err != nil || !licenseKey.HasValidSignature(publicKey) {
	fmt.Println("License key activation failed!")
	return
}

More examples can be found here.