Tools and libraries for generating cryptographic keys, constructing license strings, creating detached Ed25519 signatures, and validating JWT-based license tokens.
Audience: devs/ops who provision keys and run CLI flows.
mvn -q -DskipTests packageKeys are written to files only (never printed). On POSIX systems, files are set to 600 when supported.
A) AES key (default 256‑bit) for encrypting Keycloak UUID (forms the opaque part of the license key):
# Writes to {DIR}/aes.key (Base64)
mvn -q org.codehaus.mojo:exec-maven-plugin:3.5.1:java \
-Dexec.mainClass=io.github.bsayli.license.cli.KeygenCli \
-Dexec.args="--mode aes --size 256 --dir /secure/keys"B) Ed25519 keypairs
- Detached signature keypair (for client → licensing-service request signatures):
# Writes to {DIR}/signature.public.key and {DIR}/signature.private.key
mvn -q org.codehaus.mojo:exec-maven-plugin:3.5.1:java \
-Dexec.mainClass=io.github.bsayli.license.cli.KeygenCli \
-Dexec.args="--mode ed25519 --purpose signature --dir /secure/keys"- JWT signing keypair (for licensing-service to sign tokens):
# Writes to {DIR}/jwt.public.key and {DIR}/jwt.private.key
mvn -q org.codehaus.mojo:exec-maven-plugin:3.5.1:java \
-Dexec.mainClass=io.github.bsayli.license.cli.KeygenCli \
-Dexec.args="--mode ed25519 --purpose jwt --dir /secure/keys"If
--purposeis omitted for--mode ed25519, it defaults tosignature.
License key format is:
<prefix>.<opaquePayloadBase64Url>
Run:
mvn -q org.codehaus.mojo:exec-maven-plugin:3.5.1:java \
-Dexec.mainClass=io.github.bsayli.license.cli.LicenseKeyGeneratorCli \
-Dexec.args="--userId <KEYCLOAK_USER_UUID> \
--secretKeyFile /secure/keys/aes.key"Example output:
License key written to /secure/keys/license.key
The file license.key will contain the generated license string. Example structure:
BSAYLI.AQBjuG4HyAIXdvEdSJxUukHSnABx1UX_wiJJuiTeI0lLrhsmrVu9q2UMQniygjE30I5q8cinzAoTzK2K_Ax4-fy55zDrXVRpOT9PbhwVyuztyQ
The licensing-service expects a detached Ed25519 signature over canonical JSON SignatureData.
- When issuing a license (request contains a full
licenseKey): setencryptedLicenseKeyHash = Base64(SHA-256(licenseKey)) - When validating a JWT token: set
licenseTokenHash = Base64(SHA-256(token))
Use the SignatureCli (sign mode) to let the tool compute the proper hash and signature:
# Sign for license issue (hashes the full licenseKey for you)
mvn -q org.codehaus.mojo:exec-maven-plugin:3.5.1:java \
-Dexec.mainClass=io.github.bsayli.license.cli.SignatureCli \
-Dexec.args="--mode sign \
--serviceId crm \
--serviceVersion 1.5.0 \
--instanceId licensing-service~demo~00:11:22:33:44:55 \
--licenseKey BSAYLI.<opaque> \
--privateKeyFile /secure/keys/signature.private.key"# Sign for token validation (hashes the JWT token for you)
mvn -q org.codehaus.mojo:exec-maven-plugin:3.5.1:java \
-Dexec.mainClass=io.github.bsayli.license.cli.SignatureCli \
-Dexec.args="--mode sign \
--serviceId crm \
--serviceVersion 1.5.0 \
--instanceId licensing-service~demo~00:11:22:33:44:55 \
--token <JWT_FROM_ISSUE_RESPONSE> \
--privateKeyFile /secure/keys/signature.private.key"The CLI prints the canonical JSON and the Base64 signature; include the signature in your service’s request body.
# Verify detached signature
mvn -q org.codehaus.mojo:exec-maven-plugin:3.5.1:java \
-Dexec.mainClass=io.github.bsayli.license.cli.SignatureCli \
-Dexec.args="--mode verify \
--dataJson '{...}' \
--signatureB64 <base64-signature> \
--publicKeyFile /secure/keys/signature.public.key"Use POST /v1/licenses/tokens from the licensing-service project (see that README).
mvn -q org.codehaus.mojo:exec-maven-plugin:3.5.1:java \
-Dexec.mainClass=io.github.bsayli.license.cli.LicenseTokenValidationCli \
-Dexec.args="--publicKeyFile /secure/keys/jwt.public.key --token <JWT>"This verifies the EdDSA signature, enforces expiry, and prints claims (licenseStatus, licenseTier, optional
message). Use the jwt.public.key (Base64 SPKI Ed25519 JWT public key) for validation.
-
io.github.bsayli.license.commonCryptoConstants,CryptoUtils– algorithms, sizes, Base64 helpers, AES‑GCM utilsLicenseConstants– license prefix/delimiter + JWT claim keys
-
io.github.bsayli.license.licensekeyUserIdEncrypter– AES/GCM encrypt/decrypt for Keycloak UUIDLicenseKeyGenerator– builds<prefix>.<opaque>model.LicenseKeyData– immutable value object
-
io.github.bsayli.license.signatureSignatureGenerator/SignatureValidator– Ed25519 detached signaturesmodel.SignatureData– canonical JSON payload for signing
-
io.github.bsayli.license.securekeySecureKeyGenerator– AES (symmetric)SecureEdDSAKeyPairGenerator– Ed25519 keypair (SPKI/PKCS#8)
-
io.github.bsayli.license.tokenLicenseTokenJwtValidator– validates JWT (EdDSA) with public key and returnsLicenseValidationResultmodel.LicenseValidationResult– tier, status, expiration summary
-
io.github.bsayli.license.cli– runnable tools (see above)