# Runtime Decryption in WebLogic

Here are the detailed steps for encrypting and decrypting Java class files at runtime in a WebLogic server environment:

**Step 1: Encrypt the Class Files**

1. **Generate an AES Encryption Key:**

   * Use a secure method to generate an AES key.

   ```java
   import javax.crypto.KeyGenerator;
   import javax.crypto.SecretKey;
   import java.util.Base64;

   public class KeyGeneratorExample {
       public static void main(String[] args) throws Exception {
           KeyGenerator keyGen = KeyGenerator.getInstance("AES");
           keyGen.init(256); // 256-bit key
           SecretKey secretKey = keyGen.generateKey();
           String encodedKey = Base64.getEncoder().encodeToString(secretKey.getEncoded());
           System.out.println("AES Key: " + encodedKey);
       }
   }
   ```

   * Save the generated key securely. Example output: `AES Key: abcdefghijklmnopqrstuvwxyz1234567890ABCDEF`
2. **Encrypt the Class File:**

   * Use the AES key to encrypt the class file.

   ```java
   import javax.crypto.Cipher;
   import javax.crypto.spec.SecretKeySpec;
   import java.nio.file.Files;
   import java.nio.file.Paths;
   import java.util.Base64;

   public class EncryptClassFile {
       public static void main(String[] args) throws Exception {
           String key = "your_base64_encoded_key"; // Replace with your key
           byte[] keyBytes = Base64.getDecoder().decode(key);
           SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");

           Cipher cipher = Cipher.getInstance("AES");
           cipher.init(Cipher.ENCRYPT_MODE, secretKey);

           byte[] classFileBytes = Files.readAllBytes(Paths.get("YourClassFile.class"));
           byte[] encryptedClassFile = cipher.doFinal(classFileBytes);

           Files.write(Paths.get("YourClassFile.class.enc"), encryptedClassFile);
           System.out.println("Class file encrypted successfully.");
       }
   }
   ```

   * Replace `"YourClassFile.class"` with the path to your class file.

***

**Step 2: Deploy the Encrypted WAR File**

1. **Replace Original Class Files with Encrypted Ones:**

   * Rename the encrypted class file with the `.class.enc` extension and place it in the same directory within the WAR file.

   ```bash
   mv YourClassFile.class.enc /path/to/war/WEB-INF/classes/YourClassFile.class.enc
   ```
2. **Repackage the WAR File:**

   * Use the `jar` command to repackage the WAR file.

   ```bash
   cd /path/to/war
   jar -cvf ../encrypted.war *
   ```
3. **Deploy the WAR File:**
   * Deploy the encrypted WAR file to your WebLogic server using the WebLogic Administration Console or the command line.

***

**Step 3: Configure Runtime Decryption**

1. **Modify the Application to Decrypt at Runtime:**
   * Add decryption logic to your application to decrypt the class files at runtime before loading them.

2. **Load the Decryption Key Securely:**
   * Store the decryption key securely, such as in a secure key management service or environment variable.

3. **Implement Custom ClassLoader:**

   * Implement a custom `ClassLoader` that loads and decrypts the class files at runtime.

   ```java
   import javax.crypto.Cipher;
   import javax.crypto.spec.SecretKeySpec;
   import java.nio.file.Files;
   import java.nio.file.Paths;
   import java.util.Base64;

   public class EncryptedClassLoader extends ClassLoader {
       private SecretKeySpec secretKey;

       public EncryptedClassLoader(ClassLoader parent, String key) {
           super(parent);
           byte[] keyBytes = Base64.getDecoder().decode(key);
           this.secretKey = new SecretKeySpec(keyBytes, "AES");
       }

       @Override
       protected Class<?> findClass(String name) throws ClassNotFoundException {
           try {
               String path = name.replace('.', '/') + ".class.enc";
               byte[] encryptedClassFile = Files.readAllBytes(Paths.get(getClass().getResource("/" + path).toURI()));

               Cipher cipher = Cipher.getInstance("AES");
               cipher.init(Cipher.DECRYPT_MODE, secretKey);
               byte[] classFileBytes = cipher.doFinal(encryptedClassFile);

               return defineClass(name, classFileBytes, 0, classFileBytes.length);
           } catch (Exception e) {
               throw new ClassNotFoundException(name, e);
           }
       }

       public static void main(String[] args) throws Exception {
           String decryptionKey = "your_base64_encoded_key"; // Replace with your key
           EncryptedClassLoader classLoader = new EncryptedClassLoader(ClassLoader.getSystemClassLoader(), decryptionKey);
           Class<?> clazz = classLoader.loadClass("YourClassName");
           Object instance = clazz.newInstance();
           // Invoke methods on the instance
       }
   }
   ```

4. **Package Your Custom ClassLoader:**

   Compile your custom `ClassLoader` and package it into a JAR file. This JAR file will be included in your WebLogic server's classpath or within your application.

5. **Modify** `weblogic.xml`**:**

   The `weblogic.xml` deployment descriptor is used to configure various settings specific to WebLogic Server. To ensure WebLogic uses your custom `ClassLoader`, follow these steps:

   * Open the `weblogic.xml` file located in the `WEB-INF` directory of your application.
   * Add the necessary configurations to use your custom `ClassLoader`.

   Here’s an example of what your `weblogic.xml` might look like:

   xml

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
       http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">

       <context-root>/yourapp</context-root>

       <container-descriptor>
           <prefer-application-packages>
               <package-name>com.yourpackage.*</package-name>
           </prefer-application-packages>
       </container-descriptor>

       <library-ref>
           <library-name>custom-classloader-lib</library-name>
           <specification-version>1.0</specification-version>
           <implementation-version>1.0</implementation-version>
       </library-ref>

       <class-loader-structure>
           <class-loader-structure>
               <class-loader>
                   <name>customClassLoader</name>
                   <system-properties>
                       <property>
                           <name>encryptedClassLoader</name>
                           <value>com.yourpackage.EncryptedClassLoader</value>
                       </property>
                       <property>
                           <name>decryptionKey</name>
                           <value>your_base64_encoded_key</value>
                       </property>
                   </system-properties>
               </class-loader>
           </class-loader-structure>
       </class-loader-structure>
   </weblogic-web-app>
   ```

6. **Deploy the Application:**
   * Ensure the custom `ClassLoader` JAR file is included in your WAR file or placed in the WebLogic server's classpath.
   * Deploy the WAR file to your WebLogic server.

***

#### Important Considerations

* **Security:** Ensure that the decryption key is stored securely and not hard-coded in the application.
* **Performance:** Runtime decryption may introduce performance overhead.
* **Testing:** Thoroughly test the application to ensure that the decryption process works correctly and does not introduce any issues.
