Blog on Software Licensing, Commercialization, and Revenue Optimization

How to protect SDKs with Software Licensing in .NET

Software Development Kits (SDKs) are a great way to give your users the ability to build on top of the functionality offered by your library/package. From a licensing perspective, desktop apps and SDKs are quite similar, which we will go through in this article. We will first take a look at the applicable licensing models and then skim through some example code. You can jump directly to the tutorial here.

Licensing Models

SDK licensing is special since the developer of the SDK (the customer) is not its end user. Instead, it’s their customers that will be the end users. In this article we focus on “node-locked” and “pay per install” licensing models (you can read about all applicable licensing models here).

Node-locked is equivalent to “pay per machine”, which essentially means that each time a new machine activates the license, this is recorded so that it can be taken into account when you charge the developers (your customers). Each user will be able to re-install the app that uses the SDK any number of times, without affecting the counter.

Pay per install is similar to “pay per machine”, with the only difference being that fingerprints of the end user machines are not recorded. Instead, a counter is used that increment whenever the SDK is first launched. With this model you get a bit less control of end user instances, but since the fingerprints (aka machines codes) are not tracked, the subscription cost for Cryptolens will reduce significantly (since you are only paying per license key).

In both of the models above, you could create multiple plans for your customers that depend on the actual usage of the SDK. Eg. 1-10 could be a testing tier, 10-10,000 could be another pricing tier, and so on.


From a developer standpoint (eg. your customer), the license key will have to be specified to unlock functionality of your SDK. You could potentially have different pricing tiers depending on the methods that your customers will use. Below is an example of class initialisation that requires a license key to work.

var math = new MathMethods("FULXY-NADQW-ZAMPX-PQHUT");


To see all the code, please take a look at the entire tutorial.


If you have algorithms in your SDK that you want to be 100% secure from reverse-engineering, we would recommend to create an API endpoint for them hosted in the cloud. Most of the cloud providers support “server less” functions, eg Azure Functions and AWS Lambdas. These are quite simple to setup. Your server less functions would require a license key and potentially a machine code to return a successful response. On the client side, you could use libraries such as RestSharp to access your API endpoint. We will cover this in a future article.

Computing and verifying VAT in .NET (for EU businesses)

When you sell your software as an EU business, you need to take into account the VAT, which depends on whether you sell to a private individual or a company, and their country of residence. Moreover, you need to ensure that the VAT id that they have provided is correct.

In order to solve these two problems, we have published a library for .NET, available as a NuGet package (with source code on GitHub).


The library has two methods, CalculateVAT and IsValidVAT, which are quite simple to use. We explain their purpose below:

  • CalculateVATThis method asks for the country of residence of the individual or the company, and their VAT id (if applicable). Based on this information, it will calculate the necessary tax that should be applied to the order. Note, we assume you sell products or services that are covered by the standard VAT (i.e. some categories such as books have a lower tax in some countries).
  • IsValidVATThis method is responsible for VAT id verification. We use the European Commission’s API for that. Note, this API is not up 24/7 and can be unresponsive some times. You can view all the times it is down (given the country of residence) here.

New AI feature helps optimize software pricing

Setting the price for a product you intend to sell is hard, especially when pricing usually changes over time. Cryptolens’ new AI feature helps software providers set the price by analyzing how each individual user uses their software.

Problem with existing pricing models

It is often challenging for software providers to price their product optimally.

A good example that demonstrates this is when you set the price for accounting software. Imagine you have two groups of customers: those that use the software regularly in their profession (eg. accountants helping other companies) and those that only use it once a month (eg. small businesses). It makes sense to have different pricing models for these two groups: professionals can be charged monthly (and are very likely to pay more) and the smaller business can pay per usage (eg. per generated monthly report).

As a result, software providers are able to increase their revenues and capture both customer groups by taking into account the true value the software has for each group, and adjusting the pricing model to meet the needs for each group.

How Cryptolens’ new AI feature optimizes revenue

Cryptolens’ new AI feature analyzes the usage information generated by each user (and the history from previous users) and determines the value a product (and its features) has for each user, and then helps to determine the best pricing model for that particular user or user group.

For example, if the value of the features is higher than the price of the product, it would be reasonable to increase the price. If, however, only a subset of the product’s features are used, a new product based on a subset of the features offered at a lower price could be a solution (or potentially suggest an alternative licensing model such as usage-based model).

The goal is to provide insights on the value of a product and its features for each user, and assist in creating new product offerings with more optimal pricing.

Getting started

In order to benefit from our AI analysis, the following is required:

First, you need to register each time a customer interacts with a certain feature of the product (if you have a licenseKey object, you can call the new RegisterEvent method). For example, when they start the salary module (if it’s an accounting software), you can send FeatureName=”SalaryModule” and EventName=”start”. If they generate a report, you can keep the feature name, but change the event name to “report_generated”.

The second step is to register successful transactions (eg. when the customer buys the software). In that case, you can still call RegisterEvent method, and include the value and currency parameters.

Please get in touch with us if you need any help setting this up. We are currently looking for beta testers and would be happy if you can participate. You can reach out to us at

Once enough data is collected, you will be able to see it in the analytics dashboard.

Floating licenses supported out of the box

Floating licenses allow your customers to use a license on a limited number of machines simultaneously. For example, they can have your software installed on 100 computers, but only be able to use it on 20 of them at once.

This is similar to node-locked licenses (aka machine code locking) that is part of the Cryptolens for quite some time, with the exception that a license does not have to be deactivated when they are to be used on a new device.

Note: floating licenses are supported since v405 of Cryptolens.Licensing library for .NET. Support for C++ is coming soon.


Cryptolens Licensing for .NET (new package)

You might have noticed that we have changed from being called Serial Key Manager to Cryptolens. As a result, the design language, domains and naming of our products has changed. Now, we are also updating the .NET packages that are used to interact with the Web API. We will describe the changes below (you can also see the release notes)

New package

The new package, Cryptolens.Licensing, is essentially the same as SKGLExtension, with several improvements described below. You can either install it using NuGet or download pre-compiled binaries for the desired framework. Read more here.

.NET Standard

The new library introduces support for .NET Standard 2.0, which means more platforms in the .NET family can use it (eg. .NET Core 2.0). You can see all the supported platforms here. There is still support for .NET Framework 4.0, although most of the new features will be in the .NET Framework 4.6.

License verification on the server

Previously, most of the license validation logic was performed on the client, eg. you had to check expiration, features in the client code. The new Cryptolens client now supports the ability to create rules and perform these checks on the server. The rules are set up using feature definitions on the product page. You only need to set Metadata=True, which will give you access to the license key status. A code example is shown below (this will automatically check that the key has not expired and that it’s not blocked).

var result = Key.Activate(activateToken, new ActivateModel() 
    Key = "license",
    ProductId = 3349, 
    Sign = true, 

    Console.WriteLine("License is valid!")

A good practise is to verify the signature of this license status object, which can be done with VerifySignature. At the moment, this requires .NET Framework 4.6 or .NET Standard 2.0 to work.

3 steps how to protect your software application before release

Let’s assume that you have developed a software application (eg. app) that you are about to sell. Then, there are three things you need to consider:

  • Licensing – this is used to keep track of the type of features that end users have bought. A simple example of this when your user has to type a license key to unlock more functionality. When selecting these kinds of systems, it’s important that the system both supports offline mode and is cloud-based. The advantage of cloud-based systems is that they are more scalable and secure (eg. you have full control of all end users).
  • Obfuscation – this is used to make your program binaries (eg. exe and dll files) harder to disassemble. This is especially important for .NET apps, since existing tools make this very simple. A word of warning though: none of the available systems are 100% safe, and even the well-respected systems are being cracked within days of software release.
  • Web API – imagine your algorithm is so important that you don’t want to risk it being leaked. Since obfuscators are never 100% safe (mainly because in the end, the code will be executed on the client machine), the only secure way is to never run this code on client machines that you don’t control. Instead, you can create a Web API method that you host yourself and then allow your program to consume it. In this case, the algorithm is safe at the cost of constant internet access requirement.

To sum up, the first system to consider is licensing, since this will remove the administrative burden of keeping track of the type of rights your customers have to the software. As a bonus, many cloud-based licensing systems support integration with payment processors. In the end of the day, the goal is to ensure payments and license verification are automated, so that you can focus on developing the features that really matter to your customers.

For more information, please see this page.

New Analytics Dashboard for Software License Management

Today, we are happy to share a new version of the analytics dashboard (available to all customers), which includes many new cool features. We will sum this up in this post. The new analytics dashboard will be improved continuously, with the aim to offer more in-depth analysis of the data.

If you have any feedback, we would be happy to hear from you!

Getting Started

  1. Login on your account:
  2. Go to
  3. Click on the link on the top of the page to visit the new page.

Note: After a while, the new page ( will redirect you back to the old page. To view it again, you just need to click on the link again. We will fix this in the coming weeks.

Feature Walkthrough

World Map and Filters (by country)

To start with, you will see all the data that has accumulated since the beginning (“all time” option). You can control this easily with the 5 buttons available in the top menu (we will discuss how to set a custom time period a bit later).

The map allows you to examine stats from specific regions. You can select the desired countries and then click on “show/hide filters” and click on the “filter” button close to the country tags, as shown below (filtering on Sweden and Norway). Once we have activated the filter, it will turn blue. You can then click on the filter again and it will turn white, meaning it’s no longer active.


If you are interested in a different time region than those supported on the top menu, you can use the timeline to select an area of interest. To reset the timeline, just double-tap on it.

Time of Day

One way to understand how your application is being used is by examining when it’s used during the day. This was already available in the old analytics dashboard. The key difference in the new one is that it takes into account the local time zone of the end user.

Most Active Customers and Other Metrics

The last part includes a short summary of the key metrics such as how many licenses were created and how many requests were made during a specific time period. Moreover, it’s now also possible to compare “how active” license keys and customers are relative to each other. For instance, in the customer list, you can see your top most active and inactive customers, which can help you to discover the early adopters in a technology adoption lifecycle model.

User Accounts instead of License Keys

The common way of distributing licenses has always been using license keys (or files). Each time a customer needs more features, they have to get a new license key. Thanks to a cloud-based solution such as SKM, it’s possible to limit the number of licenses a customer needs to keep track of, since you can always change the properties of a license in the control panel.

With the “user login authentication” feature, we want to take distribution of licenses a step further and make it even more seamless for you and your customers. Below are some of the benefits of using user login authentication:

Benefits of User Login Authentication

  • Security – an account is much easier to protect than a license key (SKM has many security mechanisms in place, including two-factor authentication).
  • Time – if your customer loses a license key, they will first of all contact you, which will require more maintenance time per customer (SKM account can always be restored automatically and if more support would be needed, we will take care of it).
  • Trust – every user account comes with an easy-to-use control panel that makes it easier for your customers to manage their licenses.

Getting Started

A quick way to get going with user login authentication is by watching a short video and reviewing an example implementation on GitHub.

Note: In addition to SKM Client API, you need to install Cryptolens.SKM, which requires .NET Framework 4.6.2 or above (or .NET Core 1.0 or above). Cryptolens.SKM targets .NET Standard 1.4, so if you target any other .NET friendly platform, you can find more information here.

If you have any feedback or suggestions, please contact us at support (at)

Useful Facts & Links

New Client API for C++

We have now finalized the last bits that were left to make the C++ client API more reliable and easier to integrate. This is great news if you develop applications in C++ (for instance, drivers, connected products as a service, IoT products, and more).

Right now, it offers the activation method, which is the method that should always be called to either verify or activate a license. If there are other methods that you would find useful, please get in touch with us.

The project has been lead by Martin Svedin, Lead Developer.

On the technical side

Our client API in C++ is quite different from its .NET counterpart. The main difference is in error handling, the protocol under the hood and the ability to perform API requests outside of our API (which uses curl by default). Extensions functions (ability to chain together several constraints together) in the C++ client are similar to the .NET client.

How to perform activation

In the .NET client, the only object you need is LicenseKey. In the C++ client, there is a similar class called LicenseKey (which contains license key parameters such as features). However, in order to retrieve a LicenseKey object, you cannot just call the activation method. Instead, you need to use an intermediate class called RawLicenseKey. That is, when you call the activation function, it will return a RawLicenseKey, which can be used to create a LicenseKey object.

The only difference between RawLicenseKey and LicenseKey is that the former one contains signature whereas the latter one does not. If you want to support offline activation, you should save RawLicenseKey object (the license and the signature, as described here). However, when you verify the license parameters, LicenseKey should be used instead.

Adding constraints

Adding a chain of constraints on LicenseKey object is very similar to the way it is done in .NET. For example, in .NET, to check that feature 1 is enabled and the key has not expired, you would type:

licenseKey.HasNotExpired().HasFeature(1).IsValid() // returns true if the constraints are satisfied

In the C++ client, it’s quite similar:

license_key->check()->has_not_expired(123456789)->has_feature(1) // returns true if the constraints are satisfied

A minor difference is that has_not_expired requires the current time as a Unix time stamp in seconds.

Public Key extraction

Another point worth mentioning is how you insert your public key (not the access token) into the C++ client. You can find your RSA public key here that has a structure similar to the one below:


When you specify the modulus and exponent, you can just copy them directly from your public key as shown below:

skm_handle.signature_verifier.set_modulus_base64(e, "sGbvxwdlDbqFXOMlVUnAFgteQ==");
skm_handle.signature_verifier.set_exponent_base64(e, "AQAB");

This has to be done before any activation request is sent, as shown here.


This was a short summary of the C++ client, with focus on users that are familiar with our .NET client. For further information, please see the GitHub repository and API documentation Please get in touch with us should you have any questions! One more thing, please review the third party licenses when you are ready to release your application.

We’ve updated the license agreement to comply with GDPR

This week we’ve updated our terms of use, which now includes a new separate document (named Agreement) that clarifies the way your data is processed. In addition, we have also changed the party that provides the service, which is now Cryptolens AB. General Data Protection Regulation (GDPR) will be enforceable May 25th, 2018.

Important Considerations

When your customers are running your application, personal information such as the IP address is sent to Cryptolens AB. GDPR aims to protect users’ privacy, which means that it is important that you have a consent from your customers in doing so.

To make sure that you are compliant, our lawyer has composed an excerpt that you can insert into your agreement.

Binding the agreement to your customers

If you are targeting a large number customers, it may not be feasible to get a signed copy of the agreement. Instead, there are several ways you can make it binding online. We have listed several suggestions below:

  1. Before your customers can use your application, they should have opened a window that shows the Terms of the agreement (if you have your own end user license agreement) together with the Consent to personal data processing.
  2. It must be ensured that your customers have read the documents before they can use your application. There are different ways to do this and a function with a non-pre-filled box can be used. The customer must actively tick the box to approve the Terms of the agreement and the Consent to personal data processing.

If you would have any questions, please feel free to contact us.