Skip to content

Commit 68aaaa4

Browse files
authored
Offline activation support + floating (#10)
* Add support for floating and overdraft * Add SaveAsString and LoadFromString + refactor * Fix bug in LoadFromString * Remove redudant prints * Add customer and dataobject * Add comments * Update example * Fix a bug in LoadFromString * Update readme
1 parent a1029b2 commit 68aaaa4

File tree

13 files changed

+289
-136
lines changed

13 files changed

+289
-136
lines changed

.idea/misc.xml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 129 additions & 98 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ This repository contains examples of how to verify license keys in Java applicat
55
This library is continuously being improved. Please contact us at [email protected] should you have any questions.
66

77
## Example
8+
9+
### Key verification
810
The following example is similar to what is covered in the [key verification tutorial](https://help.cryptolens.io/examples/key-verification).
911

1012
Assuming you have referenced the `cryptolens.jar` file, the code below should generate successful result. A working project with the code below can be found in the [example-app](https://github.com/Cryptolens/cryptolens-java/tree/master/example-app) folder.
@@ -40,3 +42,15 @@ In order to adjust this code to your products, several parameters needs to be ch
4042
* `key` - the license key to be verified (above it's MPDWY-PQAOW-FKSCH-SGAAU).
4143
* `machine_code` - the unique id of the device, which may require root access. Note, this value is not the same as the one generated by the .NET client.
4244

45+
### Offline activation (saving/loading licenses)
46+
Assuming the license key verification was successful, we can save the result in a file so that we can use it instead of contacting Cryptolens.
47+
48+
```java
49+
String licenseString = license.SaveAsString();
50+
```
51+
52+
When loading it back, we can use the code below:
53+
54+
```java
55+
LicenseKey newLicense = LicenseKey.LoadFromString(RSAPubKey, licenseString);
56+
```

example-app/src/Main.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,25 @@
44
public class Main {
55

66
public static void main(String[] args) {
7-
String RSAPubKey = "<RSAKeyValue><Modulus> sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
7+
String RSAPubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
88
String auth = "WyIyNjA5IiwiaWE5b0VFT3Q2eDlNR2FvbHBHK2VOYUZ4bzNjT3h5UkNrMCtiYnhPRSJd";
99

1010
LicenseKey license = Key.Activate(auth, RSAPubKey, new ActivateModel(3349, "ICVLD-VVSZR-ZTICT-YKGXL", Helpers.GetMachineCode()));
1111

12+
System.out.println(license);
13+
1214
if (license == null || !Helpers.IsOnRightMachine(license)) {
1315
System.out.println("The license does not work.");
1416
} else {
1517
System.out.println("The license is valid!");
1618
System.out.println("It will expire: " + license.Expires);
19+
20+
21+
// Saving and loading a license (for offline use)
22+
String licenseString = license.SaveAsString();
23+
LicenseKey newLicense = LicenseKey.LoadFromString(RSAPubKey, licenseString);
24+
25+
System.out.println(newLicense.Expires);
1726
}
1827
}
1928
}

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<groupId>io.cryptolens</groupId>
55
<artifactId>cryptolens</artifactId>
66
<packaging>jar</packaging>
7-
<version>1.3</version>
7+
<version>1.4</version>
88
<name>cryptolens</name>
99
<description>A client api to access Cryptolens Licensing API.</description>
1010
<url>https://github.com/cryptolens/cryptolens-java</url>

src/main/java/io/cryptolens/methods/Helpers.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class Helpers {
1515

1616
/**
1717
* Returns a unique identifier of the device. Note, root access may be required.
18-
* Furthermore, this method is not the same as the one used in our .NET client.
18+
* Note, this method is not the same as the one used in our .NET client.
1919
*/
2020
public static String GetMachineCode() {
2121

@@ -27,16 +27,49 @@ public static String GetMachineCode() {
2727
* @returns True if the license is registered with this machine and False otherwise.
2828
*/
2929
public static boolean IsOnRightMachine(LicenseKey license) {
30+
return IsOnRightMachine(license, false);
31+
}
32+
33+
/**
34+
* Check if the device is registered with the license key.
35+
* @param isFloatingLicense If this is a floating license, this parameter has to be set to true.
36+
* You can enable floating licenses by setting @see ActivateModel.FloatingTimeInterval.
37+
* @returns True if the license is registered with this machine and False otherwise.
38+
*/
39+
public static boolean IsOnRightMachine(LicenseKey license, boolean isFloatingLicense) {
40+
return IsOnRightMachine(license, isFloatingLicense, false);
41+
}
42+
43+
/**
44+
* Check if the device is registered with the license key.
45+
* @param license The license key object
46+
* @param isFloatingLicense If this is a floating license, this parameter has to be set to true.
47+
* You can enable floating licenses by setting @see ActivateModel.FloatingTimeInterval.
48+
* @param allowOverdraft If floating licensing is enabled with overdraft, this parameter should be set to true.
49+
* You can enable overdraft by setting ActivateModel.MaxOverdraft" to a value greater than 0.
50+
*
51+
* @returns True if the license is registered with this machine and False otherwise.
52+
*/
53+
public static boolean IsOnRightMachine(LicenseKey license, boolean isFloatingLicense, boolean allowOverdraft) {
3054

3155
String current_mid = Helpers.GetMachineCode();
3256

33-
if (license.ActivatedMachines == null){
57+
if (license == null || license.ActivatedMachines == null){
3458
return false;
3559
}
3660

37-
for (ActivatedMachine machine : license.ActivatedMachines) {
38-
if(machine.Mid.equals(current_mid))
61+
if(isFloatingLicense) {
62+
if(license.ActivatedMachines.size() == 1 &&
63+
(license.ActivatedMachines.get(0).Mid.substring(9).equals(current_mid) ||
64+
allowOverdraft && license.ActivatedMachines.get(0).Mid.substring(19).equals(current_mid))) {
3965
return true;
66+
}
67+
} else {
68+
69+
for (ActivatedMachine machine : license.ActivatedMachines) {
70+
if(machine.Mid.equals(current_mid))
71+
return true;
72+
}
4073
}
4174

4275
return false;

src/main/java/io/cryptolens/methods/Key.java

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,35 +39,7 @@ public static LicenseKey Activate (String token, String RSAPubKey, ActivateModel
3939
return null;
4040
}
4141

42-
try {
43-
Base64.Decoder decoder = Base64.getDecoder();
44-
45-
byte[] licenseKey = decoder.decode(result.licenseKey);
46-
byte[] signature = decoder.decode(result.signature);
47-
48-
// setting up the signatures
49-
JavaSecuritySignatureVerifier signatureVerifier = new JavaSecuritySignatureVerifier();
50-
int mstart = RSAPubKey.indexOf("<Modulus>");
51-
int mend = RSAPubKey.indexOf("</Modulus>");
52-
int estart = RSAPubKey.indexOf("<Exponent>");
53-
int eend = RSAPubKey.indexOf("</Exponent>");
54-
signatureVerifier.setModulusBase64(RSAPubKey.substring(mstart + 9, mend));
55-
signatureVerifier.setExponentBase64(RSAPubKey.substring(estart + 10, eend));
56-
57-
if (!signatureVerifier.verify(licenseKey, signature)) {
58-
System.err.println("Signature check failed");
59-
return null;
60-
}
61-
62-
String s = new String(licenseKey, StandardCharsets.UTF_8);
63-
LicenseKey license = new Gson().fromJson(s, LicenseKey.class);
64-
license.RawResponse = result.RawResponse;
65-
66-
return license;
67-
} catch (Exception ex) {
68-
System.err.println(ex.getStackTrace());
69-
}
70-
return null;
42+
return LicenseKey.LoadFromString(RSAPubKey, result.RawResponse);
7143
}
7244

7345
}

src/main/java/io/cryptolens/models/ActivatedMachine.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package io.cryptolens.models;
22

33
public class ActivatedMachine {
4+
5+
/**
6+
* The machine code.
7+
*/
48
public String Mid;
59
public String IP;
610
public long Time;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package io.cryptolens.models;
2+
3+
public class Customer {
4+
public int Id;
5+
public String Name;
6+
public String Email;
7+
public String CompanyName;
8+
public long Created;
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.cryptolens.models;
2+
3+
public class DataObject {
4+
public int Id;
5+
public String Name;
6+
public String StringValue;
7+
public int IntValue;
8+
}

0 commit comments

Comments
 (0)