22/**
33 * Jummania.php
44 *
5- * Replicates the Java Jummania class in PHP:
6- * 1. Generates an AES-128 key, encodes it without padding, shifts each char +1
7- * 2. Reverses that to recover the raw key
8- * 3. Encrypts a URL with AES/ECB/PKCS5Padding, Base64-encodes it, then shifts each char −1
9- * 4. Shifts back +1, Base64-decodes, and decrypts to recover the original URL
5+ * A PHP implementation that mirrors the functionality of the Java `Jummania` class.
6+ *
7+ * Features:
8+ * 1. Generates a 128-bit AES key, Base64-encodes it (without padding), and shifts each character by +1.
9+ * 2. Reverses the obfuscation to recover the raw key by shifting characters by -1 and Base64-decoding.
10+ * 3. Encrypts a URL using AES/ECB/PKCS5Padding, Base64-encodes the result, and shifts each character by -1.
11+ * 4. To decrypt, shifts characters back by +1, Base64-decodes, and decrypts to retrieve the original URL.
12+ *
13+ * Author: Jummania
14+ * Date: 2024-05-14
15+ * Email: sharifuddinjumman@gmail.com
16+ * Location: Dhaka, Bangladesh
1017 */
1118
1219
3542// 1. Generate a lightweight AES-128 key (16 raw bytes)
3643$ base64Key = rtrim (base64_encode (random_bytes (16 )), '= ' );
3744
38- // 2. Obfuscate the key: shift each character by +1
39- $ encKeyChars = '' ;
40- for ($ i = 0 , $ l = strlen ($ base64Key ); $ i < $ l ; $ i ++) {
41- $ encKeyChars .= chr (ord ($ base64Key [$ i ]) + 1 );
42- }
43-
44- // 3. Function to reverse key obfuscation
45- function getSecretKey (string $ keyStr ): string
45+ // 2. Reusable function to shift characters
46+ function shiftChars (string $ input , int $ shift ): string
4647{
47- $ decoded = '' ;
48- for ($ i = 0 , $ l = strlen ($ keyStr ); $ i < $ l ; $ i ++) {
49- $ decoded .= chr (ord ($ keyStr [$ i ]) - 1 );
48+ $ output = '' ;
49+ for ($ i = 0 , $ l = strlen ($ input ); $ i < $ l ; $ i ++) {
50+ $ output .= chr (ord ($ input [$ i ]) + $ shift );
5051 }
51- return base64_decode ( $ decoded ) ;
52+ return $ output ;
5253}
5354
54- $ secretKey = getSecretKey ($ encKeyChars );
55+ // 2. Obfuscate the key: shift each character by +1
56+ $ encKeyChars = shiftChars ($ base64Key , +1 );
57+ $ secretKey = base64_decode (shiftChars ($ encKeyChars , -1 ));
5558
5659// 4. Encrypt the text and shift each char by -1
5760function encryptShift (string $ plainText , string $ key ): string
5861{
5962 $ encrypted = openssl_encrypt ($ plainText , 'AES-128-ECB ' , $ key , OPENSSL_RAW_DATA );
60- $ b64 = base64_encode ($ encrypted );
63+ $ b64 = rtrim ( base64_encode ($ encrypted), ' = ' );
6164
6265 $ shifted = '' ;
6366 for ($ i = 0 , $ l = strlen ($ b64 ); $ i < $ l ; $ i ++) {
@@ -68,34 +71,84 @@ function encryptShift(string $plainText, string $key): string
6871
6972$ shiftedEnc = encryptShift ($ string , $ secretKey );
7073
71-
74+ $ created = date ( " d/n/y " );
7275$ javaCode = <<<JAVA
76+ /**
77+ * The {@code Jummania} class demonstrates AES encryption key reconstruction and
78+ * decryption of a string that was obfuscated using character shifting and Base64 encoding.
79+ * <p>
80+ * This is an example of lightweight obfuscation layered on top of symmetric encryption,
81+ * suitable for scenarios where additional obscurity is desired beyond encryption.
82+ *
83+ * <p><b>Note:</b> This code is for educational or internal use only and not recommended for
84+ * production-grade cryptographic implementations.
85+ *
86+ * <p><b>Created by:</b> Jummania
87+ * <br><b>Date:</b> $ created
88+ * <br><b>Email:</b> sharifuddinjumman@gmail.com
89+ * <br><b>Location:</b> Dhaka, Bangladesh
90+ */
7391public class Jummania {
74- public static String getString() {
92+
93+
94+ /**
95+ * Retrieves the decrypted original string using a hardcoded encrypted text and secret key.
96+ * <p>
97+ * This method internally constructs a {@link javax.crypto.SecretKey} from a predefined obfuscated Base64 key string,
98+ * and then decrypts a predefined obfuscated and Base64-encoded string using that key.
99+ *
100+ * @return the decrypted original string
101+ * @throws Exception if any error occurs during key reconstruction or decryption
102+ */
103+ public static String getString() throws Exception {
75104 javax.crypto.SecretKey secretKey = getSecretKey(" $ encKeyChars");
76105 return getString(secretKey, " $ shiftedEnc");
77106 }
78107
79- public static javax.crypto.SecretKey getSecretKey(String key) {
108+
109+ /**
110+ * Converts an obfuscated Base64-encoded AES key string into a SecretKey object.
111+ * The input string is shifted by -1 on each character before Base64 decoding.
112+ *
113+ * @param key The obfuscated Base64-encoded AES key string
114+ * @return SecretKey instance for AES algorithm
115+ */
116+ public javax.crypto.SecretKey getSecretKey(String key) {
80117 String string = shiftChars(key, -1);
81118 byte[] decodedKey = java.util.Base64.getDecoder().decode(string);
82119 return new javax.crypto.spec.SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
83120 }
84121
85- public static String getString(javax.crypto.SecretKey secretKey, String encryptedText) {
86- try {
87- String string = shiftChars(encryptedText, 1);
88- java.util.Base64.Decoder decoder = java.util.Base64.getDecoder();
89- byte[] encryptedTextByte = decoder.decode(string);
90- javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES");
91- cipher.init(javax.crypto.Cipher.DECRYPT_MODE, secretKey);
92- return new String(cipher.doFinal(encryptedTextByte));
93- } catch (Exception e) {
94- return null;
95- }
96122
123+ /**
124+ * Decrypts an encrypted Base64-encoded string using the provided AES secret key.
125+ * <p>
126+ * The input string is first character-shifted (each character increased by 1),
127+ * then decoded from Base64, and finally decrypted using AES.
128+ *
129+ * @param secretKey the AES {@link javax.crypto.SecretKey} used for decryption
130+ * @param encryptedText the obfuscated and Base64-encoded string to decrypt
131+ * @return the original plain text after decryption
132+ * @throws Exception if any decryption step fails (e.g., decoding, cipher initialization, or decryption)
133+ */
134+ public static String getString(javax.crypto.SecretKey secretKey, String encryptedText) throws Exception {
135+ String string = shiftChars(encryptedText, 1);
136+ java.util.Base64.Decoder decoder = java.util.Base64.getDecoder();
137+ byte[] encryptedTextByte = decoder.decode(string);
138+ javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES");
139+ cipher.init(javax.crypto.Cipher.DECRYPT_MODE, secretKey);
140+ return new String(cipher.doFinal(encryptedTextByte));
97141 }
98142
143+
144+ /**
145+ * Applies a character-wise shift to each character in the input string.
146+ * For each character c, returns (char)(c + shift).
147+ *
148+ * @param input The input string to be shifted
149+ * @param shift The integer shift to apply (positive or negative)
150+ * @return The shifted string after applying the character shift
151+ */
99152 public static String shiftChars(String input, int shift) {
100153 StringBuilder result = new StringBuilder();
101154 for (char c : input.toCharArray()) {
0 commit comments