Skip to content

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

CODEMeaning
SECRET_KEY_NOT_FOUNDNo user with the specified key was found.
LICENSE_NOT_FOUNDNo such license key was found.
LICENSE_NOT_ASSIGNEDThe license key does not match the secret key.
BAD_IP_ADDRESSNot a valid IP address. (Failed to get api address from query)
BLACKLISTED_IPThe IP address from the query has been blocked.
BLACKLISTED_HWIDThe equipment identifier has been blocked.
PRODUCT_NOT_FOUNDThe product assigned to the license key does not exist.
PRODUCT_NOT_MATCHProduct assigned to the license key does not match the specified product.
MAX_IP_IN_USEThe maximum number of ip addresses for the specified license key has been reached.
MAX_MACHINES_IN_USEThe maximum number of hardware IDs for the specified license key has been reached.