2

TL;DR How do you build an airtight license control system for your onprem application, which revokes access once subscription ends?


Premise

I am building this application in Python that needs to be deployed on premise of the client. This application runs constantly like a service spewing out stats. This application is based on a subscription model.


Considerations

  1. Ensuring the IP is intact as the application resides on the client.
    • Achieving this by building a binary using Cython
  2. When subscription ends the application should not run.
    • Thinking of using HOTP(HMAC based OTP) so each client will have a seed baked into the executable. HOTP uses a seed and time to generate a symmetric key. So for every time slot say 1 month, a new key should be given to the executable.

Questions

  1. Is there a better way to achieve this?
  2. How can the application keep time in tamper-proof way? (As OS time is not reliable).
    Or
    How do I store the count of time slots in a secure way such that it cannot be hacked?
  3. As this is a service that is always running, how do I enforce a check at the end of a time slot like 1 month? Also as the application is on-prem, it can be shut down.

One ugly way is encrypting and storing an timer.txt which is constantly updated by a separate python process. Is there a better way?


The above is with consideration of no-internet.

But even if internet exists, it does not guarantee a fool-proof solution, because the network can be monitored and calls to an API can be redirected to a local service with the same name. Does this mean there should be two-way SSL here?

Christophe
  • 74,672
  • 10
  • 115
  • 187
arvindkgs
  • 129
  • 3
  • Creating an airtight licensing system can become very expensive. Be sure to not only consider what is technically possible, but also the cost aspect. There will be a point where the cost of building/maintaining the licensing system is higher than the potential losses due to non-paying users. – Bart van Ingen Schenau Feb 12 '20 at 11:49
  • I updated “”licensing” (which means granting a license, and sounds very legal and out of scope here) with “license control”. Is this ok for you? – Christophe Feb 12 '20 at 12:53
  • https://en.wikipedia.org/wiki/Software_license_server – Robert Harvey Feb 12 '20 at 14:44
  • https://stackoverflow.com/a/9035522/3608792 – Dan Wilson Feb 12 '20 at 15:22
  • If you don't control the hardware, this turns into the DRM problem. You can't guarantee the licensing system because it can always be patched out. So it's a matter of how hard do you want to make it to crack Vs the burden on you and legitimate customers. – user1937198 Feb 12 '20 at 15:39
  • Why do you want it air tight? Most real software I have seen deployed have nothing to something basic and relly on suing detected infractors if they do not pay up. – lijat Feb 12 '20 at 21:15

1 Answers1

2

Licensing is difficult, which is one of the reasons there are third party products to enforce licensing for you. And in the context of this question we are simply talking about license enforcement. You do have to define what you mean by "airtight", and whether you support licensing enforcement on private networks.

By running a Python based application, you already are at a disadvantage because python byte code can be easily disassembled and the enforcement code can be disconnected. You'll find that an appropriate solution has to be implemented in layers:

  • Step 1: automated obfuscation tools (change variable names to non-displayable characters, etc.) This can break your code.
  • Step 2: define when the licensing starts and ends, this information needs to be local to the application
  • Step 3: define how licensing is applied (per user, per machine, per user/per machine), this affects 1: where you can store this information and 2: how you identify the user or machine
  • Step 4: Define the license token that contains the start/expiration dates and the identifiable information
  • Step 5: Store that token in appropriate space (user roaming storage, user local storage, machine storage) and verify on program startup--erroring out if the license token does not exist or is no longer valid

Per User licensing only verifies the running user account against the licence grant.

Per Machine licensing only verifies the running machine--which can be difficult when PCs are so modular--against the license grant.

Per User/Per Machine needs to verify that the user and machine combination are correct against the license grant. Same user on another machine would require a new grant, just like a different user on the same machine would require a new grant.

For some scenarios (like Microsoft products) you simply need a token that encodes the product id and expiration. Simple existence of the token is sufficient to make the product usable.

Some application providers want to sign the license token (like RedGate) which creates an identifier token that gets sent to a central server, and that server sends a signed token back that has the expiration date. Because the exchange requires an active connection to their servers, they have to make special provision for users on a disconnected network. I.e. they need to allow users to copy the token as a file from the private network to the public one, upload it manually, and copy the signed token back to the private network.

The general concepts are the same. The robustness of the license enforcement (or DRM) depends on how that license token is generated and validated. Key factors for a secure token include:

  • Detection if the token has been tampered with (digital signing ensures this)
  • Method to identify the licensed party (i.e. user, machine)
  • Method to identify licensing terms
  • Method to determine if the clock has been tampered with (i.e. changing the date of the machine)

You have to think through the following:

  • How much protection do I really need? The trade-off is the more you do to enforce the license the less your customers will want to use it--particularly if they have to deal with a private network
  • How much business am I really losing? At some point, the effort someone needs to go through to defeat your licensing mechanisms is just not worth pursuing.
  • Does my DRM defeat my ability to support the application? Obfuscation tools can do terrible things here.

I am positive you will find you need a solution that is less than "airtight". It might be worth looking at existing DRM tools, and see if they can be incorporated so you aren't spending a large engineering effort on this problem.

Berin Loritsch
  • 45,784
  • 7
  • 87
  • 160
  • Thank you for your detailed response. I have explored multiple options to make my code as un-readable as possible: 1. Using PyInstaller to get an exe. But according to documentation this can be reversed. 2. Building a Docker Image. But the files can still be obtained by 'docker cp' 3. Using Cython to generate C files which then can be compiled to a platform dependent binary. This is what I am leaning towards. Yet, unsure how secure it is. Regarding licensing, it's messy. A separate licensing server, that my onprem software needs to talk to and validate its subscription, is cleaner. – arvindkgs Feb 13 '20 at 06:04
  • Thank you for your suggestion on DRM. I am looking into it. – arvindkgs Feb 13 '20 at 06:22
  • Just FYI: ARM's official IDE (Keil MDK) uses (or at least used) a third-party licensing product. The same one as Allegro/OrCAD electronics CAD suite. – jaskij Feb 13 '20 at 08:01