Documentation Index
Fetch the complete documentation index at: https://help.cryptolens.io/llms.txt
Use this file to discover all available pages before exploring further.
Platform
Expiry date
How does expiry date work?
How does expiry date work?
Expires. The question is, how can we create licenses that never expires?It turns out that expiration date will not affect the validity of a license by default. For example, all code snippets provided in the key verification tutorial assume that a license is time-unlimited.This may feel a bit counter-intuitive and we are continuously working on improving the APIs to make this more trivial.For now, if you see that a code-example contains a call to the activate method (which all examples do at the moment), it means that you need to check the expiration date even if you get a successful result. A way to do this is to call HasNotExpired (depending on the library) or simply check the Expire field. If you plan to support both time-limited and time-unlimited licenses, you can use one of the feature flags as a way to distinguish this. Please read more here.How do I block expired licenses?
How do I block expired licenses?
- if the license key has a data object with the name cryptolens_stripesubscriptionitemid, since these licenses are managed by Stripe through the recurring billing module.
- if start countdown upon activation (aka trial activation) is enabled, provided that the maximum number of activations has not been reached. For example, if you have created a license with
start countdown upon activation=trueandMaxNoOfMachines=1, it will not be blocked if it has not been activated. This way, you can pre-generate the licenses and ensure that your customer can still activate them, even when the expiration date has passed. However, once it has been activated, it will be blocked after the new expiration date (assuming that the license is marked as time-limited).
How do I start the time limit from the moment the license activates?
How do I start the time limit from the moment the license activates?
How to specify which license is time-limited?
How to specify which license is time-limited?
Maximum number of machines
Maximum number of machines is a way to specify how many unique machine codes can be added to a certain license (using theActivate method). When the limit is reached, no more machine codes will be added. There are two special cases that is important to keep in mind:
What happens when Maximum number of machines is set to zero?
What happens when Maximum number of machines is set to zero?
Helpers.IsOnRightMachine() will return false if no machine code is registered with the license, which will be the case if maximum number of machines is set to 0. As a solution, please check the MaxNumberOfMachines field, ensuring it is not 0, before calling Helpers.IsOnRightMachine().What happens when Maximum number of machines is decreased?
What happens when Maximum number of machines is decreased?
How can access can be restricted to specific machines?
How can access can be restricted to specific machines?
- Node-locked: Either you restrict a license to a certain number of machines indefinitely (i.e. until they are deactivated)
- Floating: or you allow a license to “float” between different machines, as long as at any one point this upper bound of machines is never exceeded
What's the difference between Node-locked vs. floating licenses?
What's the difference between Node-locked vs. floating licenses?
ActivatedMachines property of a LicenseKey or in the list of Activated devices (in the dashboard). You will need to deactivate unused devices if want to allow new devices to use the license.In the floating license case, the devices will be registered with the license key temporarily and it will therefore not be possible to list all of them in ActivatedMachines property. Only the floating license device that is being activated in the request will be shown.FloatingTimeInterval variable. If a device fails to send a request (aka heartbeat) within that interval, it will automatically be deactivated and other devices will be able to activate (i.e. use that seat).
FloatingTimeInterval is set to 100 by default and can easily be changed.What is the friendly name?
What is the friendly name?
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08. If you customer has many end users (i.e. activated devices), navigating between these device fingerprints can become troublesome. To resolve this, you can provide a FriendlyName when you call Key.Activate. At the time of writing, this is supported in our .NET client.There are a couple of ways you can compute the friendly name for a particular user. At this point, our recommendation is to set it to Environment.MachineName. For example, if your customers use Active Directory, the machine name will show up in the list of devices (for a particular user) in Active Directory Admin dashboard:
What is an end user / machine code?
What is an end user / machine code?
Key.Activate method with MachineCode=Helpers.GetMachineCode(). The Helpers.GetMachineCode() will return a device fingerprint that is unique for each device.However, there are other ways end users can be defined. The choice will depend on your specific licensing model. We will briefly outline several other ways it can be defined:Per processIf your customers will be able to run multiple instances on the same machine, you can define the end user so that includes the process id in addition to the fingerprint of the device. For example, it can be defined in .NET as follows:Protocols
Cryptolens uses two different protocols to deliver license key information to the client during activation:- .NET compatible (aka LingSign): if you use C# or VB.NET (unless you use Unity/Mono specific methods, in which case Other languages protocol is used)
- Other languages (aka StringSign): if you use C++, Java or Python
Securing your account with 2FA
We recommend to set up two factor authentication to secure your account. At the moment, we support the TOTP protocol. You can install an authenticator app on your phone or use Yubico authenticator in case you have a Yubico security key. For example, if you have Yubikey, you can active two factor authentication as follows:- Visit the two factor set up page.
- Click on “Enable two step authentication”.
- Open Yubico authenticator and click on the plus sign to add a new account. If the QR code is visible, Yubico Authenticator will automatically recognize it. We recommend to require touch to access the credentials.
- Save the backup code in a secure place.
- You have now successfully enabled two-factor authentication!
Client APIs / SDKs
Machine code generation
Machine code generation
.NET
Prior to v4.0.15, machine codes have used following code to gather device specific information and later hash it using either SHA1 or SHA256. The problem with this method is that it is Windows specific and requires System.Management (which is not supported in Mono when integrating with Unity). To solve this, we opted for platform specific methods to retrieve the UUID. You can read more about how to migrate here. Depending on the platform, the following shell calls are made to retrieve the UUID:WindowsTwo methods are currently being used. In older versions of the library (and when v=1), the following command is used in platform independent methods (i.e. with PI extension).cat /proc/device-tree/model), we will extract the “Serial” by running the following command:Helpers.GetMachineCodePI(v:2) in .NET, you will get the same machine code generated on Windows as in the Python library with similar settings.Java
In Java, the following method is used by default.Since v1.23, you can generate the same machine code as in the Python library and .NET libraries by callingHelpers.GetMachineCode(2) on Windows. It will use the UUID of the device and works in the cryptolens-android.jar, which does not depend on slf4j.Python
In Python, similar to .NET, we opted for UUID, which can be provided by the OS. You can see the source code here. Note, the machine code will not be the same as in .NET with default parameters. If you callHelpers.GetMachineCode(v=2) in Python and Helpers.GetMachineCodePI(v: 2) in .NET, the machine code will be the same on Windows.C++
In C++, we use the same method that was used in .NET prior to v4.0.15. The source code can be found here. We are working on shipping a platform independent version in the next release.Plan ahead
Our plan is to introduce a platform independent method to retrieve the UUIDs, in order to ensure that machine codes are the same for all client libraries. Currently, there is a way to get the same machine code on Windows in .NET and Python clients.Protecting RSA Public Key and Access Tokens
Protecting RSA Public Key and Access Tokens
RSA Public Key, Access Token and ProductId.RSA Public Key
The RSA public key is used to verify a license key object sent by Cryptolens. This is especially useful if you want to implement offline activation since we don’t want any of the properties (eg. features and expiration date) to be changed by the user.Note: the RSA public key can only be used to verify a license key object, the private key that is used for signing is stored on our server.
Access Token
An access token tells Cryptolens who you are (authentication) and what permissions are allowed (authorization). In other words, it can be thought of as username and password combined, but with restricted permission.It’s recommend to restrict access tokens as much as possible, both in terms of what it can do (eg. Activate or Create Key) and what information it returns (read more here). For example, you should preferably only allow access tokens used in the client application toActivate a license key. The permission to Create Key should only be accessible in applications that you control, eg. on your server.So if you have a restricted access token, the chances that an adversary will be able to do any harm is minimal. For example, the worst that an adversary can do is to activate more devices (up to a certain limit), which can be fixed quite easily in the dashboard.Troubleshooting
Troubleshooting
| Error message | Description |
|---|---|
Unable to authenticate | The access token is wrong. It is also shown if the subscription has expired. API access requires an active subscription. |
Something went wrong. Please contact [email protected] and we will try to fix it. | A temporary server error. Try again with a new request. |
No active subscription found. Please contact support. | No active subscription is associated with the account and thus the API call failed. The error can be fixed by updating your billing information and add a valid payment method on the billing page. |
Access denied | The access token is correct but it does not have sufficient permission. Make sure that if you, for example, want to call GetKey that the access token has “GetKey” permission. |
Not enough permission and/or key not found. | If you have checked that the product contains the license key and the access token has the right permission to call the method, this error can be fixed by setting Key Lock to -1 when creating the access token (assuming that you are working with data object related methods). |