Cloud services are adopted by both start-ups and enterprises in recent years. However, it comes security issues. At this point, developed codes differ from the data. Critical data should be stored as encrypted. On the other hand, developed codes are mostly installed on server vulnerably. For istance, Java projects could be installed on a server as a jar/ear extention file. This files include java classes hierarchically. However, there are several decompilers extract original java codes from class files.

Vlog
You can either continue to read this tutorial or watch the following video. They both cover the same topic.
🙋♂️ You may consider to enroll my top-rated cryptography course on Udemy

Java Class Loader
What if the developed code includes patentable algorithm? An enterprise might protect its intellectual property. In this case, installing the project on a server directly would be like turkeys voting for Christmas. So, what we are saying is that we should encrypt the important codes just as critical data, store them in cloud database, and decrypt it on runtime to protect intellectual property. In this way, custom codes would be still secure even if the cloud system is invaded because encryption key would not be stored on cloud system.
Suppose that we would like to protect the following code.
public class CoreClass { public static void main(String[] args) { System.out.println("hello world!"); } }
First of all, we need to compile it and generate a class file. Running a java file generates its class in Eclipse IDE. Alternatively, you might execute javac command in command prompt to generate class. The content of standard class file is partially readable and understanable as mentioned below. That’s why, these files are reversible. PS: pay attention that source file does not include package definition line.

The following code would encrypt the class file.
public class ClassEncryption { public static void main(String[] args) throws Exception{ String path = "C:\\crypto"; String classname = "CoreClass"; String algorithm = "AES"; byte[] key = {75, 110, -45, -61, 101, -103, -26, -25, 55, -70, 19, 51, 66, -91, -35, 19}; //128 bit key System.out.println(Arrays.toString(key)); encrypt(path, classname, algorithm, key); } public static void encrypt(String path, String classname, String algorithm, byte[] key) throws Exception{ Path file = Paths.get(path+"\\"+classname+".class"); byte[] content = Files.readAllBytes(file); Cipher encryption = Cipher.getInstance(algorithm); encryption.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, 0, key.length, algorithm)); byte[] encryptedContent = encryption.doFinal(content); writeToFile(path, classname, encryptedContent); } public static void writeToFile(String path, String filename, byte[] content) throws Exception{ FileOutputStream out = new FileOutputStream(path+"\\encrypted\\"+filename+".class"); out.write(content); out.close(); } }
Encrypted class content is neither readable nor understanable anymore as indicated below.

Of course, encryption key should be generated randomly with the following code instead of using static key.
KeyGenerator generator = KeyGenerator.getInstance(algorithm); generator.init(128); //generate 128 bit key SecretKey secretKey = generator.generateKey(); byte[] key = secretKey.getEncoded();
Now, we need to develop custom class loader as illustrated below. Standard class loader is responsible for loading classes. This action is handled by findClass method. We would overwrite this method, and put decryption process before defining class.
public class EncryptedClassLoader extends ClassLoader{ public Class findClass(String path, String name, String algorithm, byte[] key) throws Exception{ byte[] b = loadClassData(path, name, algorithm, key); return defineClass(name, b, 0, b.length); } private byte[] loadClassData(String path, String name, String algorithm, byte[] key) throws Exception { Path file = Paths.get(path+"\\"+name+".class"); byte[] encryptedContent = Files.readAllBytes(file); //System.out.println(new String(encryptedContent)); Cipher decryption = Cipher.getInstance(algorithm); decryption.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, 0, key.length, algorithm)); byte[] decryptedContent = decryption.doFinal(encryptedContent); //System.out.println(new String(decryptedContent)); return decryptedContent; } }
Finally, we could decrypt a class file on runtime as shown below.
public class CryptoCodeProject { public static void main(String[] args) throws Exception{ String path = "C:\\crypto\\encrypted"; //source of encrypted file String classname = "CoreClass"; //name of encrypted file String algorithm = "AES"; byte[] key = {75, 110, -45, -61, 101, -103, -26, -25, 55, -70, 19, 51, 66, -91, -35, 19}; //128 bit key EncryptedClassLoader myClassLoader = new EncryptedClassLoader(); Class dynamicClass = myClassLoader.findClass(path, classname, algorithm, key); Method m = dynamicClass.getMethod("main", String[].class); m.invoke(null, new Object[] {null}); } }
Running
Thus, core class is performed successfully. hello world! is dumped even though executed code doesn’t include this action.

So, we’ve mentinoned how to protect important codes on an external system. AES algorithm is applied to secure the system. AES and other Symetric key algorithms deliver high performance. That’s why, decryption can be handled on runtime very fast. Finally, I’ve shared the project on my GitHub profile.
Hopefully, you would not be like turkeys voting for Christmas.
Support this blog if you do like!
Exception in thread “main” java.lang.NoClassDefFoundError: CoreClass (wrong name: com/Encript/CoreClass)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:757)
at java.lang.ClassLoader.defineClass(ClassLoader.java:636)
at com.Encript.EncryptedClassLoader.findClass(EncryptedClassLoader.java:13)
at com.Encript.CryptoCodeProject.main(CryptoCodeProject.java:13)
It seems that you’ve encrypted a java file belonging to package com.Encrypt.CoreClass. You should not put package line in the java code. I’ve mentioned this in the post: “PS: pay attention that source file does not include package definition line.”