Offline Licenses
What is an offline license?
An offline license is a license that can be used in an offline or air-gapped computing environment, i.e. a device that has no or limited access to the public internet.
The simplest offline licenses are those which allow you to check their "authenticity", that the offline license key was indeed created by you. They have no embedded data, or at least, the data that is embedded into the key is not utilized within your code, i.e. it has no value.
More complex offline-capable licensing systems may have a useful dataset embedded inside of the key itself, which can be decoded/decrypted and utilized in your software. Embedded key datasets may include things like license expiration, grace periods and offline use limitations, customer and device information, and general license entitlement data.
How do I implement an offline license?
The easiest way to get started with an offline-capable license is to add a cryptographic scheme to a new Policy. Choosing a cryptographic scheme will instruct our systems to encrypt or sign all license keys which implement the Policy.
Cryptographic license files
Signed (and optionally encrypted) license files can be used in offline and air-gapped environments to distribute tamper-proof license and machine data. A license file consists of an encoded certificate, which typically looks something like this certificate below:
-----BEGIN LICENSE FILE-----eyJlbmMiOiJsSTc4N0QwcGZua1RvRDVOSjFpRXlaU093Q09QQ0NOdktKZHpC MlpSYlZBQzVsQUhjdzJSUi8xTEhrcXc0ZG5rUEl3TFVYRzhmUzk1R0JWTmtzd2JDTmllWm1uOElHeGpkbUY2T1RmNjRzOHlpbFRpL3FlUzJSTlhBdGJBWjUw
QWtpVnBudmFWTFhVdkY1UGJJYjNFRXA0YlZNOU1xWjBhNjhQa1R1MW5VS0E0QWRnV1FHWU1tU2hKdmIxbys0UFozYXU3a1FuWkZ1bWNPUUdUcllYRng1YVpZWkw3SzhGMWFFRWh1clNmNzdwa25yWXRScnBmS2tUT2QvN3RaUXhQSW16bWpjOTVGeWJlY0ladndEU2NTNGpRM2VCYlU0cHRFd056dlc5ay9JRFBja2N2eWdBNFhhUnFsRkNZYlRDa1R3LzBZbUVxQnJVTThCYWpFZ3dTRWdvNG44c2N0UTNJVncxYkx6cnVFWDEzY1B3eXE1UDM5SVY5TFlhUjhVYmZBR0tBT0YzbGlPZUppZStmKy96cDFGK2NrcFBIM3J6OW5XbTVjOEFzWkxKeUR3NmFBK1hDRHdmRThlWXdrQlpLTFB4SUJ5Qm9QemIwaU5NWmwya25sU2R1d2hZNUhIVktKbTVKWXR1eGVHK1FOcjFEZXg2NlVXWGJuVHNKT1M3Mlo4NVBBZFFSTjV4SmlHVW92akE0anI2RVJDcDBtWlhMQnM2RXljb2tnYi91cFRWRDV0Y0lRZ2YvSkZGcC96VnNrUjNDdEl5UHk2YUZUNGZIM1N3djFxZ1p6OHBtcUM0aDB6OWR1WlhXeUdzM0p1aGJSWmFpMG9IOTA5Z1V0anR4MHJ4SEg2OUdBamtHWCtQQ2w4QlN4ZlBPMVJsTktPSmw2ckZZVzVac0pIUWhzNnQvZkx5eGJUTEg5YVlUNm5sV0s0eUZ3M3JIVC9oMnlia0NJSjFtMGRQV0pFTkhqTGFzLzFZME5XK28rbXYvR2UyT2NlZ3FjQ2QxSmFLTis3dk13eTlSQ050d1IyeUt1dWIrQzU2aVdhVjQvanNqbmZyVHFZOU0reFZuNlFNM3djVUhwODJ3TzlySWNQOCtxcWtVQmQrYjUxMnVyUW5EbFRObi9JRE1jWGs5SUVWV09QQXdNMDBCV0U5TTFmU2xaTjRldlh6akx6N0c5L3dEbGsxZThMU0FDTEhzcUFSVEZVNzhLMmp3bmlodW9UeHE4TlNSLyswS013elVaVE03WGVHQnVHZVhZT25XUG5YUzlsRFJ6QlMrbE1sT0tZQTJxZzMrSEJSRDR0bS9XaGpRWFRQN250bEQ1MUFKRDRrc3U1NER2dWlqaXJoQmNwaVNYbjliRzV4dE8vQ0dhNlJQbGJJWkxaTjRnY1FjeDhkckdXV0Z2QnA4YVVqVlBWNlFoZ0lqREpDNG9QcDBXNkgyUEdFTC9jbXRMV3JaOVMzTUcvWFRHazFVZnZtNGFMekdQaEoyRGw4TFV3TEhmbGNvVEYvUFg3dDQ2aUlMQnpXdlV4MmU4MEpMakNMaXkrU1VOcnJTMXhqdUQ2R0NqWU9DeVh5TUhJYmlwd09PVEJKbXdvYmorWEh4QkZQY0J5bnBYVlM5ZWVlbEE5Nk8yV0xRZVdFYkFMQXJTcyt1RXJqSjFDZ3o5RjdDVjFnNGp5M2VPQVRDTUJHK1JlVE9KSUdyQ2xmZkt2N2laMmxKS1p4VTRodnExTjVwaEVwZ09KUC91K1M1Zi8zaFBHaXRIVUw0VzFJbS9CR1E3WDFQMHNmbkkySDJlVm8vRmU0L0J0VHQ0eUVUK1lpUkJyWGNsZWxUTWM0R0pENzRocVI4RGxxY0VBLy8xWThnSldCQlNqa0hHYlpiMHRsZ0ZnenpuYzAxUDRJVXByQ21ueEkzeXVVVXJWNDlQL25UcGRkVzJoNDFpUzNoSitSdzVuaHk0QWhZVDdOTVFER1h1cEw3Q29BUWphb0FTc3NZdGJSWDhheGdocTk5a1BYaVRCVVIycEM4ZHpaMnBtbGVqZjY1ck15TktabkRtWkNDanBIS1R3MnpnUzU2V3hoUXdxbnRoRlR0R2prTllKWDEyMm5McVF6T0crTThzWitqUDEzNWRGUUo3L1Y2eFNWOHFnRkJGaHVueHk3N3NoNXZadzVNaDNlOFQvMzh6d3FqYWpCWlYraDVPU05veEpjMlJrMGgxTjFlaUc2TUtUMDVlNDNVRkczcTBKNkJGdHkvL25qYU9EM1ZpVVBadkxGTEVpZFo0eG4vRzg0WDhjNDFtUjd4SEZmbVIxcTFTeTBYRFZLT2laRnhxdDJyYU5RV0wrWlQ2bWRDMEliNkg3Rm55cjdpbHFzRzNCWjNVbjE4UkRmdlkrb3NjNlN0bDA1bEoxdTJYTUNvZ2xEZDJpcnNzSjBZL29DU0Q1ZVE0SnRtL0xrSk81T0Z0ckJ5VnZEUGZkZ2ZTUnk4UU5pamNSNFBJUXBsNkNUQjJXQjBQWFN5VmRiaFVpRWZncE8xeXJRYnJobFFya0pPTFlDdnMwNCtMVjdUclVoRTF2aXFLY2ZVUXMwQnVvNjZOSy8yZDBJOWprRnM4ZzlWSzFqcE9RUU9BVjNoZTA1T01Lck5nNW5NUktPYTQxTUF5U1FpVlg3NHZhdEF3Y0lSelBTTmlOUFR3emFDdllBNUx3d0ovUW1kblpHeEVBSFZRV0VwKzBzNDNVc2lRMFNTdDRMVjVlMWlZMDl1aks4b2thazB6ZGUrRHd0RTlqdzlzTEhTdzRzZGpUUzNIZEN6aFZmVms0ZXZDZVB4NDhwQjk2QllFUHh5SCs5SUppcXE2eU8xTnRIZHBlWUk3TWpueTV6RkEzTk5UdkR1N0FOMmhnT0R2OXBUM2ZNWklZNnNua0RiU0RyVXhhMnBRUldaU3ZtK2hHeUowbHo2ZnhoU0FmM3hRaGpCb0V6bnRlblNTZm1QWEpLbmJoMmJhTnNrdVVIb1lOMVNmL2orRUxCU1dTd0NSbWtOZGI1UkhCQWswdk41QmVLSDVPM3ZlZXRBc2NjdGZMV0R3aDliWnB4ZHVLaFVMeTdLQXl4S1pFbjloWFVUMzhaKzFGTVdzY3RJbDB2anZSSXdpbkMwNFRPUHVqSkh0NXJkMVZRZ0pkTGNDdzQ5TThuSzRSbjlINkwwVWM2dUc4cWRHZXhLY2xyZU1KWmxCTlJsVm5pTzc0VnVoMkVMajk5UWJ2VUhTZ205QllHZmk4aDAwNUFGb0VvNDRxNnpYK0ZNc3daR0txQUpQd0ZCd0x1VGNsa1BIemYvUjlzazZQSkNrOWF1M0t4end3R1ArMkM0RzRaSEhGcUI4dVhldlYyZmR6SExTbTc2cTNkYlRVZ285YXJWLzZBc2ZTaFJacW9HZlhHNVdGRjBsYThMNU0zb21XY3JSeUR6R2ZwQ1BwUXJJNFQyUnN5Vmp6NDFwNHB0dEpUd0lla0tucEtjOWsvcFliR1hodi82cHFpY1hhN1Q5bUplT2Uxc1AxYm15UmJPTWorWXJadmVDaGlrTFFCQlI2U2gwMG5UNHpYL1l2RjRjNVNNM3NKK1pTejVaVXRJSGZiOFRrNWdsYWlzN2VYNTdjYXlxOHdmeVFSOVJlQzNPR0l5YWUyblZ4ZzE3RDBOeXBxTFJBOXFRMU1TSEFka2ZSMEdsWUpueFF4NThtT1J4Z2Fia2V5MExLeE5hRzdzaytKMVljRnUyTEhCNnp3S0t0dThLZGdtVTdHdHZoZz0uQmFHSEZJTExMQ3dNb3RkRC5pejZ5N1NxS0R0QXhGWTNsUlluMVZBPT0iLCJzaWciOiJyMWFjNjFocUcramZsc0p1RjFTUWRxUUQvYTd3L1Y4QndDMWNvdU5iaHo5ai9s TlJWWGp6Ym5DRkF6V3lOU3NUeG9xZm9MV2FlWlhITEZnR21Ub2VBdz09IiwiYWxnIjoiYWVzLTI1Ni1nY20rZWQyNTUxOSJ9 -----END LICENSE FILE-----
This certificate is cryptographically signed using Ed25519 or 2048-bit RSA, and optionally encrypted using AES-256-GCM.
The embedded data payload contains a tamper-proof snapshot of a license or machine resource, with any included relationship data, as well as metadata indicating the expiration date of the license file.
License files can be generated via the API from an internet-connected device, such as a mobile device, and then transferred to devices in the air-gapped environment using email, a USB drive or other means.
The following cryptographic algorithms are available:
aes-256-gcm+ed25519
aes-256-gcm+rsa-pss-sha256
aes-256-gcm+rsa-sha256
base64+ed25519
base64+rsa-pss-sha256
base64+rsa-sha256
For further information on license files, check out the API reference.
Signed license keys
Signed license keys are made up of an encoded dataset and a signature. These values can be parsed in your software application and crytographically verified using ECC or RSA.
Below is a breakdown of a signed license key's format:
The encoded dataset is completely under your control, and can be arbitrary text, a JSON object, XML, or any other text format. But you can also use the default dataset, which is a JSON object, if you don't have any specific requirements. In this example, we'll use the user's email.
Parsing the dataset and verifying its authenticity can be performed like so:
The signing prefix and encoded dataset are delimited by a /
character (forward slash), while
the signing data and the signature are delimited by a .
character (dot).
The following policy signing schemes are available:
RSA_2048_PKCS1_PSS_SIGN_V2
RSA_2048_PKCS1_SIGN_V2
ED25519_SIGN
For further information on signing schemes, check out the API reference.
Encrypted license keys
Encrypted license keys are similar to signed keys, but the format is a lot simpler. Encrypted licence keys solely consist of an embedded dataset. In this example, we'll use the user's email address as the embedded dataset.
Below is an example of decrypting an encrypted key:
Successfully decrypted keys can be utilized within your software, or discarded after a successful decryption if the embedded dataset is not needed elsewhere. Encrypted keys that fail decryption should be considered invalid.
The following policy encryption schemes are available:
RSA_2048_PKCS1_ENCRYPT
For further information on encryption schemes, check out the API reference.
Common embedded datasets
Common values we see embedded inside of cryptographic keys:
- An expiration date (keep in mind that embedded data is immutable so expiration dates may not be the best choice for a renewable key)
- The duration a license is allowed to be offline (e.g. 1 year of offline use before an online reactivation is required)
- A fixed "grace period" for the license (e.g. the license is allowed to be used for 5 days after the expiration date)
- The maximum application version to which the licensee is entitled
- Known hardware or appliance identifiers (e.g. for node-locking licenses up-front)
- Customer or licensee information (e.g. email address)
- Other entitlement information
Code examples
Here are a few code examples our team has put together for implementing cryptographic licensing schemes in offline and air-gapped environments:
- https://github.com/keygen-sh/example-python-cryptographic-machine-files
- https://github.com/keygen-sh/example-rust-cryptographic-license-files
- https://github.com/keygen-sh/example-csharp-cryptographic-license-files
- https://github.com/keygen-sh/example-java-cryptographic-license-keys
- https://github.com/keygen-sh/example-dart-cryptographic-license-files
- https://github.com/keygen-sh/example-csharp-cryptographic-verification
- https://github.com/keygen-sh/example-cpp-cryptographic-verification
- https://github.com/keygen-sh/example-python-cryptographic-verification
- https://github.com/keygen-sh/example-embedded-license-key-data
- https://github.com/keygen-sh/example-cryptographic-verification
- https://github.com/keygen-sh/example-bash-cryptographic-verification
- https://github.com/keygen-sh/air-gapped-activation-example
Here are some examples of utilizing response signatures:
- https://github.com/keygen-sh/example-python-offline-validation-caching
- https://github.com/keygen-sh/example-validation-caching
- https://github.com/keygen-sh/example-electron-license-activation
- https://github.com/keygen-sh/example-signature-verification
Perpetual License | Timed License | Floating License | Node‑locked License | Feature License | |
---|---|---|---|---|---|
Expiration Date | No | Yes | Optional | Optional | Optional |
Activation Limits | Optional | Optional | > 0 | 1 | Optional |
Feature Limits | Optional | Optional | Optional | Optional | Yes |
Offline Support | Yes | Yes | Yes | Yes | Yes |
Learn More | Learn More | Learn More | Learn More | Learn More |