# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://calvin-lai.gitbook.io/calvin-lai-security/application-security/modifying-and-protecting-java-class-files/techniques-to-protect-java-class-files/runtime-decryption-in-weblogic.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
