diff --git a/README.md b/README.md new file mode 100644 index 00000000..72e156b0 --- /dev/null +++ b/README.md @@ -0,0 +1,168 @@ +# 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 name +- `str2` - Last name +- `str3` - Product name +- `str4` - Email address + +**Process:** + +1. **Input Validation** - Check all parameters are non-null and non-empty + +2. **Concatenation** - Create byte array by concatenating: + ``` + lastName + productName + firstName + lastName + email + ``` + +3. **Byte Reversal** - Reverse the entire byte array + ```java + 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; + } + ``` + +4. **Character Transformation** - Apply mathematical formula to each byte: + ```java + 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; + } + ``` + +5. **Special Character Handling** - Modify specific ASCII codes: + ```java + 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) + +6. **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 name +- `str2` - Last name +- `str3` - Product name +- `str4` - Secret/seed value +- `str5` - Email address + +**Process:** + +1. **Get Obfuscated String** - Call Method 1 to get obfuscated base string + +2. **MD5 Hashing** - Create MD5 hash: + ```java + 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 + ``` + +3. **Checksum Generation** - Create 4-byte checksum using custom algorithm + +4. **Combine Checksum and Hash**: + ``` + result = checksum (4 bytes) + hash (16 bytes) = 20 bytes total + ``` + +5. **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 1 +- `str7` - Additional field 2 + +**Changes from Method 2:** + +1. **Lowercase Conversion** - firstName, lastName, and email are converted to lowercase + +2. **Extended Base String**: + ``` + obfuscated(firstName.toLowerCase(), lastName.toLowerCase(), product, email.toLowerCase()) + field1 + field2 + ``` + +3. **Modified MD5 Process**: + ```java + md5.update(input); + md5.update(input); + md5.update((input + field1).getBytes()); // Additional update with field1 + byte[] hash = md5.digest(); + ``` + +4. **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`): + +```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