Maybe somebody is interested in this code. It’s relatively easy to create AquaticPrime license keys in Java once you know how. I used it last year on Google App Engine to generate my licenses for a promotion.

First, you need the imports:

  1. import java.security.KeyFactory;
  2. import java.security.MessageDigest;
  3. import java.security.spec.RSAPrivateKeySpec;

Next, you have to store the public and private keys in the Java class:

  1. private static final String privkeyStr = "…";
  2. private static final String pubkeyStr = "…";

You can get those from the AquaticPrime Developer application. Don’t include the “0x” prefix! Use a single line for the whole key.

Next, you have to generate the data to sign. The keys-value-pairs included in the dictionary have to be sorted by key (case insensitively). For simplicity, I only did the following for my Cockpit licenses:

  1. String total = email + name + "Cockpit Single User";

This data has to be hashed using SHA1:

  1. MessageDigest digest = MessageDigest.getInstance("SHA1");
  2. digest.update(total.getBytes("utf8"));
  3. byte[] hash = digest.digest();

The data has to be encrypted using RSA with the private and public keys mentioned above. For this, you first have to convert the hex strings to BigIntegers, and then create a new RSAPrivateKeySpec object out of them:

  1. RSAPrivateKeySpec privkey = new RSAPrivateKeySpec(new BigInteger(pubkeyStr, 16), new BigInteger(privkeyStr, 16));

Next, the RSA cipher can be initialized:

  1. KeyFactory factory = KeyFactory.getInstance("RSA");
  2. Cipher cipher = Cipher.getInstance("RSA");
  3. cipher.init(Cipher.ENCRYPT_MODE, factory.generatePrivate(privkey));

Your final license key looks like this:

  1. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
  2. "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" +
  3. "<plist version=\"1.0\">" +
  4. "<dict><key>Email</key><string>" + email + "</string>" +
  5. "<key>Name</key><string>" + name + "</string>" +
  6. "<key>Product</key><string>Cockpit Single User</string>" +
  7. "<key>Signature</key><data>" + Base64.toString(cipher.doFinal(hash)) + "</data>" +
  8. "</dict></plist>"

Note that there are a lot of exceptions to catch there, but the compiler informs you about them anyways :)

« »