Registration Key Algorithm
This document describes the registration key generation algorithm found in app/src/main/java/bH/C0997e.java.
Overview
The algorithm generates registration keys for product licensing using a multi-step process that combines user information, applies various transformations, and generates a cryptographic hash.
Algorithm Steps
Method 1: Basic Obfuscation
a(String str, String str2, String str3, String str4)
Parameters:
str- First namestr2- Last namestr3- Product namestr4- Email address
Process:
-
Input Validation - Check all parameters are non-null and non-empty
-
Concatenation - Create byte array by concatenating:
lastName + productName + firstName + lastName + email -
Byte Reversal - Reverse the entire byte array
for (int i = 0; i < bArr.length / 2; i++) { byte temp = bArr[i]; bArr[i] = bArr[(bArr.length - 1) - i]; bArr[(bArr.length - 1) - i] = temp; } -
Character Transformation - Apply mathematical formula to each byte:
for (int i = 0; i < bArr.length; i++) { byte b = bArr[i]; int transformed = (b + ((b - 32) % 7)) - (i % 4); if (transformed > 122) { transformed -= 9; } bArr[i] = (byte) transformed; } -
Special Character Handling - Modify specific ASCII codes:
for (int i = 0; i < bArr.length; i++) { if (bArr[i] == 96 || bArr[i] == 92 || bArr[i] == 91 || bArr[i] == 93 || bArr[i] == 59 || bArr[i] == 46) { bArr[i] = (byte) (bArr[i] + 6 + (i % 10)); } }Special characters affected:
`(96),\(92),[(91),](93),;(59),.(46) -
Return - Convert byte array to string
Method 2: Registration Key Generation (5 Parameters)
a(String str, String str2, String str3, String str4, String str5)
Parameters:
str- First namestr2- Last namestr3- Product namestr4- Secret/seed valuestr5- Email address
Process:
-
Get Obfuscated String - Call Method 1 to get obfuscated base string
-
MD5 Hashing - Create MD5 hash:
MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] input = (obfuscatedString + secret).getBytes(); md5.update(input); md5.update(input); // Update twice md5.digest(); // Digest once (discarded) md5.update(input); // Update again byte[] hash = md5.digest(); // Final digest -
Checksum Generation - Create 4-byte checksum using custom algorithm
-
Combine Checksum and Hash:
result = checksum (4 bytes) + hash (16 bytes) = 20 bytes total -
Base-32 Encoding - Convert to custom base-32 string:
Charset: "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ" (33 characters, no 'O')Each byte is mapped to a character:
char = charset[abs(byte) % 33]
Method 3: Enhanced Registration Key (7 Parameters)
a(String str, String str2, String str3, String str4, String str5, String str6, String str7)
Additional parameters:
str6- Additional field 1str7- Additional field 2
Changes from Method 2:
-
Lowercase Conversion - firstName, lastName, and email are converted to lowercase
-
Extended Base String:
obfuscated(firstName.toLowerCase(), lastName.toLowerCase(), product, email.toLowerCase()) + field1 + field2 -
Modified MD5 Process:
md5.update(input); md5.update(input); md5.update((input + field1).getBytes()); // Additional update with field1 byte[] hash = md5.digest(); -
Different Character Set:
Charset: "23456789ABCDEFGHJKLMNPQRSTUVWXYZ" (31 characters, no '1', 'I', 'O') char = charset[abs(byte) % 31]
Method 4: Full Registration Key (8 Parameters)
a(String str, String str2, String str3, String str4, String str5, String str6, String str7, String str8)
Additional parameter:
str8- Additional field 3
Changes:
- Base string includes all three additional fields:
field1 + field2 + field3 - Same character set as Method 3
Usage Context
The registration dialog calls these methods (found in app/src/main/java/ao/dQ.java):
String calculatedKey = C0997e.a(firstName, lastName, "MegaLogViewer", email);
if (calculatedKey != null && calculatedKey.equals(userEnteredKey) && !alreadyRegistered(userEnteredKey)) {
// Registration successful
}
Key Properties
- Character Sets: Custom base-32 encoding (excludes ambiguous characters like 'O', '1', 'I')
- Output Length: 20 characters (from 20 bytes)
- Hash Algorithm: MD5
- Deterministic: Same inputs always produce same key
- Case Handling: Methods 3 & 4 normalize to lowercase for consistency
Security Notes
- Uses MD5 hashing (considered weak by modern standards)
- Obfuscation through byte manipulation
- No salt/random component (deterministic output)
- Multiple hash iterations for additional complexity
- Custom encoding prevents simple reverse engineering