Java Program source code is very easy for others to peek, as long as there is an inverse compiler, anyone can analyze the code of others. This article discusses how to protect source code by encrypting technology without modifying the original program.
One, why to encrypt?
For traditional languages such as C or C + +, it is easy to protect the source code on the Web, as long as it is not published. Unfortunately, the Java program source code is very easy for others to peek. As long as there is an inverse compiler, anyone can analyze other people's code. Java's flexibility makes the source code easy to steal, but at the same time it makes it relatively easy to protect code through encryption, and the only thing we need to know is the Java ClassLoader object. Of course, knowledge of the Java Cryptography Extension (JCE) is also essential in the encryption process.
There are several techniques that can "blur" Java class files, making it much less effective for the counter compiler to process class files. However, it is not difficult to modify the counter compiler so that it can handle these obfuscated class files, so it is not easy to rely on fuzzy technology to keep the source code secure.
We can use the popular encryption tools to encrypt applications, such as PGP (Pretty Good Privacy) or GPG (GNU privacy Guard). At this point, the end user must decrypt before running the application. But after the decryption, the end user has a unencrypted class file, which is no different from the prior encryption.
The mechanism of Java running fashion into bytecode implicitly means that bytecode can be modified. Each time the JVM loads a class file, it needs an object called ClassLoader, which is responsible for loading the new class into the running JVM. The JVM gives ClassLoader a string containing the name of the class to be loaded, such as Java.lang.Object, and the ClassLoader is responsible for finding the class file, loading the raw data, and converting it into a class object.
We can modify it before the class file is executed by customizing the ClassLoader. The application of this technique is very extensive. The purpose here is to decrypt the class file when it is loaded, so it can be viewed as an instant decryption device. Since the decrypted bytecode file will never be saved to the file system, it is difficult for the spy to get the decrypted code.
Since the process of converting raw bytecode into class objects is entirely system-specific, it is not difficult to create custom ClassLoader objects, with the original data first, and any transformations that include decryption.
Java 2 simplifies the construction of custom ClassLoader to some extent. In Java 2, the default implementation of LoadClass is still responsible for all the necessary steps, but it calls a new Findclass method to take into account the various custom class loading processes.
This provides a shortcut for us to write custom ClassLoader, reducing the hassle: simply overwrite findclass, not overwrite loadclass. This approach avoids the need to repeat the public steps that all of the loader must perform, because it is the responsibility of loadclass.
However, this method is not used in the custom classloader of this article. The reason is simple. If a ClassLoader class file is found by default, it can be located, but because the class file is encrypted, it will not approve the class file and the loading process will fail. Therefore, we have to implement loadclass ourselves, a little more work.
Second, custom class loading device
Each running JVM already has a classloader. This default classloader looks for the appropriate bytecode file in the local file system based on the value of the CLASSPATH environment variable.
The application of custom ClassLoader requires a more in-depth understanding of the process. We first have to create an instance of a custom ClassLoader class and then explicitly ask it to load another class. This forces the JVM to associate the class and all the classes it needs to the custom ClassLoader. Listing 1 shows how to load a class file with a custom ClassLoader.
"Listing 1: Loading class files with custom ClassLoader"
The following are the referenced contents: First create a ClassLoader object ClassLoader Myclassloader = new Myclassloader (); Loading class files with custom ClassLoader objects and convert it into a class object. Class MyClass = Myclassloader.loadclass ("MyPackage.") MyClass "); Finally, create an instance of the class Object newinstance = Myclass.newinstance (); Note that all other classes required by the MyClass will be passed Custom ClassLoader Auto Mount |
As mentioned earlier, custom ClassLoader only need to get the data of the class file first, then pass the bytecode to the Run-time system, which completes the remaining tasks.
There are several important ways to ClassLoader. When creating a custom classloader, we simply overwrite one of them, the loadclass, to provide code to get the original class file data. This method has two parameters: the name of the class, and a token that indicates whether the JVM requires parsing the class name (that is, whether the dependent class is loaded at the same time). If this token is true, we simply invoke Resolveclass before returning to the JVM.
"A simple implementation of the Listing 2:classloader.loadclass ()"
The following are the referenced contents: Public Class loadclass (String name, Boolean resolve) Throws ClassNotFoundException { try { The class object we want to create Class Clasz = null; Required Step 1: If the class is already in the system buffer, We don't have to load it again. Clasz = Findloadedclass (name); if (Clasz!= null) return Clasz; Here is the custom section BYTE classdata[] =//* Get bytecode data in some way; if (classdata!= null) { Successfully reads bytecode data and now converts it to a class object Clasz = defineclass (name, Classdata, 0, classdata.length); } Required Step 2: If the above is not successful, We tried to load it with the default ClassLoader. if (Clasz = null) Clasz = Findsystemclass (name); Required Step 3: If necessary, load related classes if (resolve && Clasz!= null) Resolveclass (Clasz); Returns the class to the caller return Clasz; catch (IOException IE) { throw New ClassNotFoundException (ie.tostring ()); catch (Generalsecurityexception GSE) { throw New ClassNotFoundException (gse.tostring ()); } } |
Total 3 page: previous 1 [2] [3] Next page