|  | /** | 
        
          |  | * Offline Activator [Version 1.0.0 Beta] | 
        
          |  | * | 
        
          |  | * @author Bipin Jitiya | 
        
          |  | * @version 1.0 | 
        
          |  | * @since 2024-04-24 | 
        
          |  | */ | 
        
          |  |  | 
        
          |  | import javax.crypto.Cipher; | 
        
          |  | import javax.crypto.spec.SecretKeySpec; | 
        
          |  | import java.io.ByteArrayOutputStream; | 
        
          |  | import java.math.BigInteger; | 
        
          |  | import java.security.KeyFactory; | 
        
          |  | import java.security.NoSuchAlgorithmException; | 
        
          |  | import java.security.Signature; | 
        
          |  | import java.security.interfaces.RSAPrivateKey; | 
        
          |  | import java.security.spec.InvalidKeySpecException; | 
        
          |  | import java.security.spec.PKCS8EncodedKeySpec; | 
        
          |  | import java.util.ArrayList; | 
        
          |  | import java.util.Base64; | 
        
          |  | import java.util.List; | 
        
          |  | import java.util.Random; | 
        
          |  | import java.util.Scanner; | 
        
          |  |  | 
        
          |  | public class Activator { | 
        
          |  | private static final String privateKey2048 = "REPLACE_WITH_PRIVATE_KEY_2048"; | 
        
          |  | private static final String privateKey1024 = "REPLACE_WITH_PRIVATE_KEY_1024"; | 
        
          |  | private static final byte[] encryptionKey = "REPLACE_WITH_ENCRYPTION_KEY".getBytes(); | 
        
          |  | private static final boolean VERBOSE_ENABLED = true; // Set to false to disable verbose logging | 
        
          |  |  | 
        
          |  | public static void main(String[] args) { | 
        
          |  | printBanner(); | 
        
          |  |  | 
        
          |  | Scanner scanner = new Scanner(System.in); | 
        
          |  | String licenseName; | 
        
          |  |  | 
        
          |  | // Step 1: Ask for license name | 
        
          |  | System.out.print("\033[34mEnter license name: \033[0m"); | 
        
          |  | licenseName = scanner.nextLine(); | 
        
          |  |  | 
        
          |  | // Step 2: Generate license string | 
        
          |  | String license = generateLicense(licenseName); | 
        
          |  | verboseLog("Printing the generated license string..."); | 
        
          |  | System.out.println("\033[1;92mLICENSE KEY\033[0m"); | 
        
          |  | System.out.println(license); | 
        
          |  |  | 
        
          |  | // Step 3: Ask for activation request | 
        
          |  | System.out.println("\033[34mEnter activation request:\033[0m"); | 
        
          |  | String activationRequest = scanner.nextLine(); | 
        
          |  |  | 
        
          |  | // Step 4: Print activation response | 
        
          |  | String activationResponse = generateActivation(activationRequest); | 
        
          |  | verboseLog("Printing the generated activation response..."); | 
        
          |  | System.out.println("\033[1;92mACTIVATION RESPONSE\033[0m"); | 
        
          |  | System.out.println(activationResponse); | 
        
          |  | } | 
        
          |  |  | 
        
          |  | public static String generateLicense(String licenseName) { | 
        
          |  | verboseLog("Generating a license string using the entered license name..."); | 
        
          |  | ArrayList<String> al = new ArrayList<>(); | 
        
          |  | al.add(getRandomString()); | 
        
          |  | al.add("license"); | 
        
          |  | al.add(licenseName); | 
        
          |  | al.add("4102415999000"); //Time stamp (Format: Milliseconds), license expires at Thu Dec 31 2099 15:59:59 GMT+0000 | 
        
          |  | al.add("1"); | 
        
          |  | al.add("full"); | 
        
          |  | verboseLog("Adding random string, type, license name, expiration date, user count, and license level to the data..."); | 
        
          |  | verboseLog("Data prepared: "+al); | 
        
          |  | verboseLog("Signing the data using SHA256 and SHA1 algorithms with respective private keys..."); | 
        
          |  | al.add(generateSignature(privateKey2048, stringsToByteArray(al), "SHA256withRSA")); | 
        
          |  | al.add(generateSignature(privateKey1024, stringsToByteArray(al), "SHA1withRSA")); | 
        
          |  | return prepareArray(al); | 
        
          |  | } | 
        
          |  |  | 
        
          |  | public static String generateActivation(String activationRequest) { | 
        
          |  | verboseLog("Decoding the activation request to extract parameters..."); | 
        
          |  | byte[] rawBytes = decrypt(Base64.getDecoder().decode(activationRequest)); | 
        
          |  | ArrayList<String> al = new ArrayList<>(); | 
        
          |  | int from = 0; | 
        
          |  | for (int i = 0; i < rawBytes.length; ++i) { | 
        
          |  | if (rawBytes[i] == 0) { | 
        
          |  | al.add(new String(rawBytes, from, i - from)); | 
        
          |  | from = i + 1; | 
        
          |  | } | 
        
          |  | } | 
        
          |  | al.add(new String(rawBytes, from, rawBytes.length - from)); | 
        
          |  |  | 
        
          |  | if (al.size() != 5) { | 
        
          |  | return "Error decoding activation request :-("; | 
        
          |  | } else { | 
        
          |  | verboseLog("Parameters extracted: " + al); | 
        
          |  | verboseLog("Constructing an ArrayList to store activation data..."); | 
        
          |  | ArrayList<String> activationList = new ArrayList<>(); | 
        
          |  | activationList.add("41414141"); // ¯\_(ツ)_/¯ | 
        
          |  | activationList.add(al.get(0)); | 
        
          |  | activationList.add("activation"); | 
        
          |  | activationList.add(al.get(1)); | 
        
          |  | activationList.add("True"); | 
        
          |  | activationList.add(""); | 
        
          |  | activationList.add(al.get(2)); | 
        
          |  | activationList.add(al.get(3)); | 
        
          |  | verboseLog("Final activation request parameters: " + activationList); | 
        
          |  | verboseLog("Signing the data using SHA256 and SHA1 algorithms with respective private keys..."); | 
        
          |  | activationList.add(generateSignature(privateKey2048, stringsToByteArray(activationList), "SHA256withRSA")); | 
        
          |  | activationList.add(generateSignature(privateKey1024, stringsToByteArray(activationList), "SHA1withRSA")); | 
        
          |  | return prepareArray(activationList); | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | private static byte[] stringsToByteArray(List<String> list) { | 
        
          |  | try { | 
        
          |  | ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); | 
        
          |  | for (String s : list) { | 
        
          |  | byteArray.write(s.getBytes()); | 
        
          |  | byteArray.write(0); | 
        
          |  | } | 
        
          |  | return byteArray.toByteArray(); | 
        
          |  | } catch (Exception e) { | 
        
          |  | e.printStackTrace(); | 
        
          |  | throw new RuntimeException(e); | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | private static String generateSignature(String pri, byte[] data, String method) { | 
        
          |  | try { | 
        
          |  | Signature sign = Signature.getInstance(method); | 
        
          |  | sign.initSign(generateRSAPrivateKeyFromHex(pri)); | 
        
          |  | sign.update(data); | 
        
          |  | byte[] signature = sign.sign(); | 
        
          |  | return Base64.getEncoder().encodeToString(signature); | 
        
          |  | } catch (Exception e) { | 
        
          |  | e.printStackTrace(); | 
        
          |  | return null; | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | public static RSAPrivateKey generateRSAPrivateKeyFromHex(String hexStr) { | 
        
          |  | BigInteger hex = new BigInteger(hexStr, 16); | 
        
          |  | byte[] priData = hex.toByteArray(); | 
        
          |  | try { | 
        
          |  | KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | 
        
          |  | PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(priData); | 
        
          |  | return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec); | 
        
          |  | } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { | 
        
          |  | e.printStackTrace(); | 
        
          |  | return null; | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | private static String getRandomString() { | 
        
          |  | verboseLog("Generating random alphanumeric string of length 32..."); | 
        
          |  | String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; | 
        
          |  | StringBuilder str = new StringBuilder(); | 
        
          |  | Random rnd = new Random(); | 
        
          |  | while (str.length() < 32) { | 
        
          |  | int index = (int) (rnd.nextFloat() * CHARS.length()); | 
        
          |  | str.append(CHARS.charAt(index)); | 
        
          |  | } | 
        
          |  | return str.toString(); | 
        
          |  | } | 
        
          |  |  | 
        
          |  | private static String prepareArray(ArrayList<String> list) { | 
        
          |  | try { | 
        
          |  | ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); | 
        
          |  | for (int i = 0; i < list.size() - 1; ++i) { | 
        
          |  | byteArray.write(list.get(i).getBytes()); | 
        
          |  | byteArray.write(0); | 
        
          |  | } | 
        
          |  | byteArray.write(list.get(list.size() - 1).getBytes()); | 
        
          |  | verboseLog("Encrypting the signed data using DES algorithm..."); | 
        
          |  | verboseLog("Encoding the encrypted data into Base64 format..."); | 
        
          |  | return Base64.getEncoder().encodeToString(encrypt(byteArray.toByteArray())); | 
        
          |  | } catch (Exception e) { | 
        
          |  | e.printStackTrace(); | 
        
          |  | throw new RuntimeException(e); | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | private static byte[] encrypt(byte[] arrayOfByte) { | 
        
          |  | try { | 
        
          |  | SecretKeySpec localSecretKeySpec = new SecretKeySpec(encryptionKey, "DES"); | 
        
          |  | Cipher localCipher = Cipher.getInstance("DES"); | 
        
          |  | localCipher.init(Cipher.ENCRYPT_MODE, localSecretKeySpec); | 
        
          |  | return localCipher.doFinal(arrayOfByte); | 
        
          |  | } catch (Exception e) { | 
        
          |  | e.printStackTrace(); | 
        
          |  | throw new RuntimeException(e); | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | private static byte[] decrypt(byte[] arrayOfByte) { | 
        
          |  | verboseLog("Decrypting the data using DES algorithm..."); | 
        
          |  | try { | 
        
          |  | SecretKeySpec localSecretKeySpec = new SecretKeySpec(encryptionKey, "DES"); | 
        
          |  | Cipher localCipher = Cipher.getInstance("DES"); | 
        
          |  | localCipher.init(Cipher.DECRYPT_MODE, localSecretKeySpec); | 
        
          |  | return localCipher.doFinal(arrayOfByte); | 
        
          |  | } catch (Exception e) { | 
        
          |  | e.printStackTrace(); | 
        
          |  | throw new RuntimeException(e); | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | private static void verboseLog(String message) { | 
        
          |  | if (VERBOSE_ENABLED) System.out.println("\u001B[36mVERBOSE: " + message + "\u001B[0m"); | 
        
          |  | } | 
        
          |  |  | 
        
          |  | private static void printBanner() { | 
        
          |  | System.out.println("\033[1;33mOffline Activator [Version 1.0.0 Beta] by Bipin Jiitya (@win3zz)"); | 
        
          |  | System.out.println("Java Version: " + System.getProperty("java.version") + "\033[0m"); | 
        
          |  | System.out.println("\n\033[1;31mDisclaimer: The Offline Activator is intended solely for academic and research purposes. \n" + | 
        
          |  | "Any misuse or unauthorized use of this tool for unethical activities is strictly prohibited. \n" + | 
        
          |  | "Researchers are responsible for adhering to ethical guidelines and legal regulations governing research activities.\033[0m\n"); | 
        
          |  | } | 
        
          |  | } |