Tag: software licensing

Software licensing for PHP applications

We recently added support for key verification in PHP, available on GitHub. Below is the sample code that can be included into your application.

<?php
require_once('Cryptolens.php');

$activate = cryptolens_activate(
      // Access token
      'WyI0NjUiLCJBWTBGTlQwZm9WV0FyVnZzMEV1Mm9LOHJmRDZ1SjF0Vk52WTU0VzB2Il0='
      // Product Id
    , 3646
      // License Key
    , 'MPDWY-PQAOW-FKSCH-SGAAU'
      // Machine code
    , '289jf2afs3'
    );

// $activate is now a boolean indicating if the activation attempt was successful or not

?>

The repository contains all the necessary information to get the code to work (eg.. finding access tokens)

Usage-based (pay per use) software licensing in .NET

Many software vendors nowadays move away from one-time payments to other licensing models. One such example is the usage-based model. By doing so helps lowering the barrier of entry for new customers, as they no longer need to commit to the product long term, which is usually the case with one-time payments. If you already have a subscription model, supporting usage-based payments can help you to monetise a group of users who would otherwise not buy the product.

You can read the entire tutorial here.

Getting started

In Cryptolens, usage-based licensing can be implemented using data objects, aka custom variables. We can use these variables to record how often features are used and keep track of any usage credits that a customer has purchased. There are two ways of billing customers:

  • Upfront payment: customers need to purchase usage credits in advance.
  • Based on actual usage: customers pay for the actual usage in the end of the billing period.

Charging based on actual usage

If you choose to charge your customers based on actual usage, we can simply use the code below:

var auth = "Access token with AddDataObject, ListDataObject and IncrementIntValue permission. Please also set KeyLock value to '-1'";
var licenseKey = "LZKZU-MPJEW-TARNP-UHDBQ";

var result = Data.ListDataObjects(auth, new ListDataObjectsToKeyModel 
{
    Contains = "usagecount",
    Key = licenseKey,
    ProductId = 3349 
});

var obj = result.DataObjects.Get("usagecount");

if (obj == null)
{
    // make sure to create it in case it does not exist.
    Data.AddDataObject(auth, new AddDataObjectToKeyModel { Key = licenseKey, ProductId = 3349, Name = "usagecount", IntValue = 1 });

    if(res == null || res.Result == ResultType.Error)
    {
        Console.WriteLine("Could not create new data object. Terminate." + res.Message);
    }
}
else
{
    var res = obj.IncrementIntValue(auth, 1, licenseKey: new LicenseKey { Key = licenseKey, ProductId = 3349 });

    if (res == false) 
    {
        Console.WriteLine("We could not update the data object. Terminate.");
    }
}

Upfront payments

If you instead want to charge your users upfront, we need to create the data objects when creating the license. If you are using payment forms, we can set up two requests, one creating a new license and another creating a new data object (inspired by this tutorial), as the result from key creation will be “piped” into data object creation request. You can then have another payment form that allows users to refill their credits, in which case the custom field can be used.

You can use the code below to verify if the limit was reached inside your application:

var auth = "Access token with AddDataObject, ListDataObject and IncrementIntValue permission. Please also set KeyLock value to '-1'";
var licenseKey = "LZKZU-MPJEW-TARNP-UHDBQ";

var result = Data.ListDataObjects(auth, new ListDataObjectsToKeyModel { Contains = "usagecount", Key = licenseKey, ProductId = 3349 });
var obj = result.DataObjects.Get("usagecount");

var res = obj.DecrementIntValue(auth, decrementValue: 1, enableBound:true, lowerBound: 0, licenseKey: new LicenseKey { Key = licenseKey, ProductId = 3349 });

if (!res)
{
    Console.WriteLine("Could not decrement the data object. The limit was reached.");
}

Sending news and update notifications using Messaging API

The new Messaging API allows you to easily send notifications to some or all of your end users. For example, it can help you to notify customers running an older version of your application to upgrade as well as keep them updated about the latest news.

Getting Started

It’s quite simple to get started with the Messaging API. The dashboard is available here, which is where you can send the messages. In order receive them in your own app, you can use the GetMessages method. One thing to keep in mind are the two optional parameter, time and channel. These allow you to tell Cryptolens which messages you want to receive. Time is used as a reference when the last message was seen and channel is a way to group those messages. If these are not specified, all of the messages will be returned.

For example, let’s say you want to implement updates notifications. In that case, we can use the code below to ensure that only older versions of the software receive the message. The version itself is specified as a unix timestamp in the currentVersion parameter, which should be the time when you published the release.

var currentVersion = 1538610060;
var result = (GetMessagesResult)Message.GetMessages("token with GetMessages permission", new GetMessagesModel { Channel = "stable", Time = currentVersion } );

if(result == null || result.Result == ResultType.Error)
{
    // we could not check for updates
    Console.WriteLine("Sorry, we could not check for updates.");
}
else if (result.Messages.Count > 0)
{
    // there are some new messages, we pick the newest one 
    // (they are sorted in descending order)
    Console.WriteLine(result.Messages[0].Content);
}
else
{
    // No messages, so they have the latest version.
    Console.WriteLine("You have the latest version.");
}

Console.Read();

You can see the entire tutorial about updates notifications for more details. There is also about notifications.

Protecting Software with Obfuscation and Software Licensing

Software applications can be secured with two layers of protection. The first layer is software licensing, whose aim is to enforce a license model (eg. by restricting the number of machines where the application can run). The second layer is software obfuscation, where the end goal is to make it hard or impossible for the end users read and alter the source code. In this article, we will focus on obfuscation.

Types of obfuscations

There are two ways of making it harder for the adversary to read or alter the source code. We can either achieve it by altering the source in such a way that more time is necessary to understand how the code works and to make it harder to remove existing licensing logic (eg. for key verification). This is usually what is thought of as obfuscation. The second approach is to move critical code away from the client machine to your own servers and provide it as an API endpoint that your application will call.

Both methods have their pros and cons. In the case of code obfuscation, you can relative easily increase the difficultly of reverse engineering at the cost of that eventually the source code will be reversed engineered or licensing logic bypassed. With custom API endpoints, you always retain control of code execution (since it runs on your servers) and if everything is correctly implemented, it’s impossible to reverse engineer the code. This is at the cost of requiring active internet connection to your server and potentially some regulatory issues (since data has to be transferred to your servers).

Conventional obfuscators

There are many obfuscators out there, some that even are free of charge. For the .NET platform, you can either use Ofuscar or ConfuserEx. The idea behind all of them is to make the IL code (which C# and VB.NET compile to) harder to read for an adversary. They should be quite easy to use, so you can simply add the key verification logic anywhere in the software.

API endpoints

Creating an API endpoint for highly sensitive code is the best way to protect it against reverse engineering. Although it may sound as very cumbersome to set up and maintain, the good news is that most cloud providers today support some form of serverless computing. We will describe how this is achieved using Azure Functions, but it should be fairly similar to other cloud platforms. The reason why we chose the serverless model is because it abstracts most things away, allowing you to focus on expressing the actual method. Moreover, cloud providers tend to allow a “per request” model, meaning that you do not have to pay for the time when the application is idle.

Azure Functions demo

To create an Azure function, go to the Azure portal and create a new “Function App”. You can then select either “consumption plan” or “app service plan” (please see this for more details). Once it’s set up, create a new HTTP Trigger and change the run.csx as shown below. To get the license verification to work, we will need to add an additional file, function.proj (or project.json for older versions of the runtime), which we cover further down in the article.

run.csx
#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

using SKM.V3;
using SKM.V3.Models;
using SKM.V3.Methods;

public static async Task Run(HttpRequest req, ILogger log)
{
    // this function will return 'Hello, <name>' if the correct license key is provided.

    // licensekey and machinecode stored as query string
    if(!KeyVerification(req.Query["licensekey"], req.Query["machinecode"])) 
    {
        return new BadRequestObjectResult("License key verification failed");        
    }
    
    string name = req.Query["name"];

    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

public static bool KeyVerification(string licenseKey, string machineCode) {

    var RSAPubKey = "<RSA public key>";

    var auth = "<access token>";
    var result = Key.Activate(token: auth, parameters: new ActivateModel()
    {
        Key = licenseKey,
        ProductId = 3349,
        Sign = true,
        MachineCode = machineCode
    });

    if (result == null || result.Result == ResultType.Error ||
        !result.LicenseKey.HasValidSignature(RSAPubKey).IsValid())
    {
        // an error occurred or the key is invalid or it cannot be activated
        // (eg. the limit of activated devices was achieved)
        Console.WriteLine("The license does not work.");
        return false;
    }
    else
    {
        // everything went fine if we are here!
        Console.WriteLine("The license is valid!");
        return true;
    }
}
function.proj

In order to add support for license key verification, we need to add Cryptolens.Licensing. Depending on the version of function apps that you are using, you might either need to create a project.json or function.proj file. The newest version of the runtime uses function.proj.

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
 
  <ItemGroup>
    <PackageReference Include="Cryptolens.Licensing" Version="4.0.9.2"/>
  </ItemGroup>
 
</Project> 

In case you get any issues with namespaces not being found, it can be useful to try to re-create the function entirely.

Accessing form client side

In order to access your method through the client application, we can use RestSharp or similar library. When you click on “Get function url”, you will get a string similar to “https://<cluster-name>.azurewebsites.net/api/HttpTriggerCSharp1?live=<secret key>”. The live parameter may not be present for some access levels

var client = new RestClient("https://<cluster-name>.azurewebsites.net/api/");
var request = new RestRequest("HttpTriggerCSharp1", Method.GET);
//request.AddParameter("code", "<secret key>"); // depending on access level of the function in Azure

// for licensing
request.AddParameter("licensekey", "AAAA-BBBB-CCCC-DDDD");
request.AddParameter("machinecode", Helpers.GetMachineCode());

// parameter to our function
request.AddParameter("name", "Bob");

var result = client.Get(request);

Console.WriteLine(result.Content);

Console.ReadLine();

If all worked out correctly, we should see “Hello, Bob” in the terminal.

Privacy

The best advice when it comes to privacy is to send as little personal identifiable information as possible. Always ask yourself what data really needs to be processed externally. Even if it is not always possible to make it entirely anonymous, it’s good to strive to at least pseudo-anonymize data (i.e. associate an id to each user instead of using their real name). In some cases, such as with IP address, you can remove the last digits, eg. from 10.1.1.5 to 10.1.1.0 without affecting the geographical data of the IP. For advanced users, you might want to look into homomorphic encryption and follow the recent research.

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: https://app.cryptolens.io/Account/Login
  2. Go to https://app.cryptolens.io/Stats
  3. Click on the link on the top of the page to visit the new page.

Note: After a while, the new page (https://analytics.cryptolens.io/index.html) 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.

Timeline

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.

How to Skip Royalties for Mobile Apps using Software Licensing

Problems with App store?

Limited Functionality

One clear problem with any App store is that you’re locked in to use their limited set of licensing models (i.e. ways to sell your app). This is evident when you want to support proper subscription based model (i.e. customers need to pay on a monthly or early basis to continue to use your app). Many big companies, such as Microsoft and Adobe, are starting to charge their customers on a recurring basis, for instance in Office 365 and Adobe Creative Cloud. Now, you no longer buy the “product” but rather the “service”, which means that we want to give our customers a great user experience independent of the platform, may it be a tablet, a smartphone or a PC. Unfortunately, this is very difficult to implement and manage across multiple platforms  if you use built in functionality of the App store (and other app stores) because you’re locked in into their ecosystem.

High Royalties

Not only are you locked in into their ecosystem, they also take 30% of your revenue that you could have used to develop your application further.

Say you sell your service for $100/per month. Then you have to pay $30 per month in royalties, which adds up to almost $400 per year. Note, this is in addition to the fee that you payed to register a developer account.

How is this solved now?

One question that comes into our mind is following: How do companies like Spotify and Uber avoid to pay Apple the 30% transaction fee? The common denominator is that they use a custom licensing component that they maintain themselves. For example, to use Spotify, you need an active subscription (even if the app is free), which you can get outside of the Apple store, for example, on Spotify’s website. So, technically, no transaction occurred in the app itself.

Solution

The idea is to avoid using the built-in functionality of the App store as much as possible. You can do this in the following two ways: either you develop a licensing component from scratch or use a third party.

Building from Scratch

If you have some time at your disposal, you can create a licensing system from scratch or use an open source library, such as SKGL. The advantage is that you get to design it specifically for your needs. Using open-source systems can save you some time, but please keep in mind that you might instead need to spend time on configuring it and possibly extending depending on your requirements.

Using Third Party

The idea here is simple: “Why invent the wheel?”. Software licensing and monetization is such a common problem so there are solutions out there that can do just that.

First of all, they will probably cover many cases and secondly they are also cheaper than doing it on your own (after all, think about the time it would take, which is approx. 2-3 months, and later maintenance).

The critical bit is maintenance. Imagine that your business model changes and you have to restructure your licensing solution. If you use a third party, they most likely have what you’re looking for, so changing won’t be hard. Otherwise, you have to do it yourself from scratch.

Example solution using SKM

In order to get a working licensing component, one way to go is to use SKM – a cloud based licensing as a service. SKM is like a toolbox that contains many of the tools that you would need to set up a licensing system within hours. In comparison to many of the alternative solutions, it’s aim is to be accessible, which includes being affordable and simple-to-use. Moreover, one of the values is transparency and developer friendliness; many of the tools used in SKM are available open source and free of charge.  It’s very simple to get started.