Basic HTTP validation
This is a simple examples of how to validate license with the mLicense API in your application.
Examples
This is simple examples for license validation is few languages.
- You need fill
INTEGRATION_KEY
constant with your account secret key. The secret key is used only to identify your user in system.
Remember usage is very simple to explain how is works for you, we recommend you to hide this checks in your application hard as possible.
You can replace this class with your own implementation of license validation, remember for use same checks.
✅ - Tested and working
Implementation
java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.NetworkInterface;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Base64;
import java.util.Scanner;
import java.util.logging.Logger;
public class ExampleBasicValidation {
private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder().build();
private static final String UNKNOWN = "unknown";
private static final String OS = System.getProperty("os.name").toLowerCase();
private static final Gson GSON = new GsonBuilder()
.setPrettyPrinting()
.disableHtmlEscaping()
.create();
private final Logger logger = Logger.getLogger("Validation");
private final HardwareCheck hardwareCheck = new HardwareCheck();
public Status valid(String apiUrl, String secretKey, String key, String product, String version) {
try {
String hardwareId = this.hardwareCheck.fetchHardwareId();
Status check = check(apiUrl, secretKey, key, product, version, hardwareId);
if (check == null) {
this.logger.severe("Check is null!");
return null;
}
return check;
} catch (Exception exception) {
this.logger.severe(exception.getMessage());
return null;
}
}
private Status check(String apiUrl, String secretKey, String key, String product, String version, String hardwareId) {
HttpResponse<String> response = this.request(apiUrl, secretKey, key, product, version, hardwareId);
if (response == null) {
return null;
}
String body = response.body();
int statusCode = response.statusCode();
JsonObject responseObject;
try {
responseObject = GSON.fromJson(body, JsonObject.class);
} catch (Exception exception) {
return null;
}
if (statusCode != 200) {
return new Status(false, responseObject);
}
String decodedHash = new String(Base64.getDecoder().decode(responseObject.get("hash").getAsString()));
boolean validHash = validHash(statusCode, decodedHash, key, secretKey);
return new Status(validHash, responseObject);
}
private JsonObject prepareData(String key, String product, String version, String hardwareId) {
JsonObject request = new JsonObject();
request.addProperty("key", key);
request.addProperty("product", product);
request.addProperty("version", version);
request.addProperty("hardwareId", hardwareId);
return request;
}
private HttpResponse<String> request(String apiUrl, String secretKey, String key, String product, String version, String hardwareId) {
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.header("Content-Type", "application/json")
.header("Authorization", secretKey)
.POST(BodyPublishers.ofString(GSON.toJson(prepareData(key, product, version, hardwareId))))
.build();
return HTTP_CLIENT.send(request, BodyHandlers.ofString());
} catch (Exception exception) {
this.logger.severe("License server is not available. Please try again later.");
return null;
}
}
private boolean validHash(int statusCode, String hash, String key, String secretKey) {
if (statusCode != 200 || hash.length() != 30) {
return false;
}
String left = key.substring(0, 4);
String secret = secretKey.substring(0, 5);
String pablo = "2520052137";
String time = String.valueOf(Instant.now().atZone(ZoneId.of("UTC+1")).toEpochSecond()).substring(0, 4);
String right = key.substring(key.length() - 4);
String status = "KIT";
return hash.startsWith(left) &&
hash.substring(4, 9).equals(secret) &&
hash.substring(9, 19).equals(pablo) &&
hash.substring(19, 23).equals(time) &&
hash.substring(23, 27).equals(right) &&
hash.substring(27).equals(status);
}
public String fetchErrorCode(Status status) {
JsonObject object = status.getObject();
if (!object.has("code")) {
return "UNKNOWN";
}
return object.get("code").getAsString();
}
public String fetchErrorMessage(Status status) {
JsonObject object = status.getObject();
if (!object.has("message")) {
return "UNKNOWN";
}
return object.get("message").getAsString();
}
public static class HardwareCheck {
public String fetchHardwareId() {
try {
if (OS.contains("win")) {
return getWindowsIdentifier();
}
if (OS.contains("mac")) {
return getMacOsIdentifier();
}
if (OS.contains("inux")) {
return getLinuxMacAddress();
}
} catch (Exception e) {
return UNKNOWN;
}
return UNKNOWN;
}
private String getLinuxMacAddress() throws FileNotFoundException, NoSuchAlgorithmException {
File machineId = new File("/var/lib/dbus/machine-id");
if (!machineId.exists()) {
machineId = new File("/etc/machine-id");
}
if (!machineId.exists()) {
return UNKNOWN;
}
try (Scanner scanner = new Scanner(machineId)) {
return hexStringify(sha256Hash(scanner.useDelimiter("\\A").next().getBytes()));
}
}
private String getMacOsIdentifier() throws IOException, NoSuchAlgorithmException {
byte[] hardwareAddress = NetworkInterface.getByName("en0").getHardwareAddress();
return hexStringify(sha256Hash(hardwareAddress));
}
private String getWindowsIdentifier() throws IOException, NoSuchAlgorithmException {
Process process = Runtime.getRuntime().exec(new String[]{"wmic", "csproduct", "get", "UUID"});
try (Scanner sc = new Scanner(process.getInputStream())) {
while (sc.hasNext()) {
if (sc.next().contains("UUID")) {
return hexStringify(sha256Hash(sc.next().trim().getBytes()));
}
}
}
return UNKNOWN;
}
private byte[] sha256Hash(byte[] data) throws NoSuchAlgorithmException {
return MessageDigest.getInstance("SHA-256").digest(data);
}
private String hexStringify(byte[] data) {
StringBuilder stringBuilder = new StringBuilder();
for (byte singleByte : data) {
stringBuilder.append(String.format("%02x", singleByte));
}
return stringBuilder.toString();
}
}
public static class Status {
private final boolean valid;
private final JsonObject object;
public Status(boolean valid, JsonObject object) {
this.valid = valid;
this.object = object;
}
public boolean isValid() {
return valid;
}
public JsonObject getObject() {
return object;
}
}
}
Usage
java
public class ExampleMain {
public static void main(String[] args) {
ExampleBasicValidation validation = new ExampleBasicValidation();
Status status = validation.valid(
"https://valid.mlicense.net/api/v1/validation",
"INTEGRATION_KEY",
"LICENSE_KEY",
"PRODUCT_NAME",
"PRODUCT_VERSION"
);
if (status == null) {
System.out.println("Failed status null.");
System.exit(1);
return;
}
if (!status.isValid()) {
String code = validation.fetchErrorCode(status);
String message = validation.fetchErrorMessage(status);
System.out.println("Invalid!");
System.out.println(code);
System.out.println(message);
System.exit(1);
return;
}
System.out.println("Success!");
}
}
Possible errors
CODE | Meaning |
---|---|
SECRET_KEY_NOT_FOUND | No user with the specified key was found. |
LICENSE_NOT_FOUND | No such license key was found. |
LICENSE_NOT_ASSIGNED | The license key does not match the secret key. |
BAD_IP_ADDRESS | Not a valid IP address. (Failed to get api address from query) |
BLACKLISTED_IP | The IP address from the query has been blocked. |
BLACKLISTED_HWID | The equipment identifier has been blocked. |
PRODUCT_NOT_FOUND | The product assigned to the license key does not exist. |
PRODUCT_NOT_MATCH | Product assigned to the license key does not match the specified product. |
MAX_IP_IN_USE | The maximum number of ip addresses for the specified license key has been reached. |
MAX_MACHINES_IN_USE | The maximum number of hardware IDs for the specified license key has been reached. |