Java integration guide

Activate, verify and deactivate with the JDK HttpClient and Ed25519.

This guide covers the full loop: activate → store → verify on startup → deactivate. It assumes you already have a workspace and a license key.

Requires JDK 15+ for Ed25519. The example uses only the standard library.

1. Activate

LicenseClient.java
import java.net.URI;
import java.net.http.*;
import java.nio.charset.StandardCharsets;

static final String BASE = "https://keygate.unionuser.com";

static String activate(String licenseKey, String deviceId) throws Exception {
    String json = "{\"license_key\":\"" + licenseKey
        + "\",\"identifier\":\"" + deviceId
        + "\",\"identifier_type\":\"device\"}";

    HttpRequest req = HttpRequest.newBuilder(URI.create(BASE + "/api/v1/license/activate"))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(json, StandardCharsets.UTF_8))
        .build();

    HttpResponse<String> res = HttpClient.newHttpClient()
        .send(req, HttpResponse.BodyHandlers.ofString());
    if (res.statusCode() != 200) throw new IllegalStateException("activate " + res.statusCode());
    // Parse token from the JSON response (use your JSON library here).
    return res.body();
}

2. Verify offline

Verify.java
import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HexFormat;

static final byte[] SPKI_PREFIX = HexFormat.of()
    .parseHex("302a300506032b6570032100");
static final byte[] RAW_PUBLIC = HexFormat.of()
    .parseHex("bf17435ee7b937b3592808941683c21d37c4e124d95d4e8fdd86fe775dd23b11");

static boolean verifyToken(String token, String deviceId) throws Exception {
    String[] parts = token.split("\\.");
    String payloadB64 = parts[0];
    byte[] signature = b64url(parts[1]);

    byte[] spki = new byte[SPKI_PREFIX.length + RAW_PUBLIC.length];
    System.arraycopy(SPKI_PREFIX, 0, spki, 0, SPKI_PREFIX.length);
    System.arraycopy(RAW_PUBLIC, 0, spki, SPKI_PREFIX.length, RAW_PUBLIC.length);

    PublicKey key = KeyFactory.getInstance("Ed25519")
        .generatePublic(new X509EncodedKeySpec(spki));

    Signature sig = Signature.getInstance("Ed25519");
    sig.initVerify(key);
    sig.update(payloadB64.getBytes(StandardCharsets.US_ASCII));
    if (!sig.verify(signature)) return false;

    // Decode payload and compare did / exp with your JSON parser.
    return true;
}

static byte[] b64url(String value) {
    String padded = value;
    while (padded.length() % 4 != 0) padded += "=";
    return Base64.getUrlDecoder().decode(padded);
}

3. Deactivate

Deactivate.java
HttpRequest req = HttpRequest.newBuilder(URI.create(BASE + "/api/v1/license/deactivate"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(json))
    .build();
HttpResponse<String> res = HttpClient.newHttpClient()
    .send(req, HttpResponse.BodyHandlers.ofString());

Desktop notes

  • Use Jackson or Gson for responses and payloads instead of manual string building.
  • On Windows, read MachineGuid with reg query, or JNA if you add the dependency.
  • Store the token under the user profile (e.g. %APPDATA%).