How to encrypt a .jar file - java

I'm working in a project where we need to encrypt the .jar file so no one can access to the .class files which inside the jar file.... is there any java coding which can help me to encrypt the .jar file ?

Even if you encrypt the jar file, it must be decrypted before the JVM is able to run it, so you'll need another jar file containing classes that decrypt and loads in the JVM.
Since this second jar file cannot be itself encrypted, a malicious user wanting to see you class files, can simply look at classes in this second jar file, and then decrypt your super-secret jar file and have access to it.
Maybe you can increase security of your code using an obfuscator, but it will eventually protect (make it harder but not impossible) your class files from decompilation, not from being used.
If obfuscation is not enough, you could consider compiling your jar file to a DLL for windows or a SO for unix/linux, that will make it much harder to decompile, but it's not always possible to do that correctly and it's generally a PITA. GCJ is able to do this somehow, and there are other commercial products that will actually compile .class/.jar directly to machine code.
However please consider that it does not matter how much security you put in it, since the client computer MUST be able to execute it, it must be able to read it, so no matter what your code will be exposed, you can only make it harder.
If you really have an algorithm so secret you don't want to disclose no matter what, consider converting it to a web service, hosting it on your server, so that you don't have to send the actual code to the client machines and can also better prevent unauthorized copies of your application by checking access to that vital part of it.

I assume you are aware of the fact that any skilled java coder can reverse-engineer the Java tool you use (or write) and still decode the app's jars? Also writing custom classloaders which read your "encrypted" code can be decompiled and a tool could be written to bypass it.
Even with obfuscation and bytecode modification and custom classloaders, java is hackable/decompileable and the source can almost always be brought to a somewhat readable state.

You want to obfuscate, not encrypt, the jar file.
A popular choice for doing this in Java is ProGuard.

No. Since your program needs to be able to run the code it would be pointless anyway.
You can obfuscate your code though so decompiling the .class files results in less readable code (meaningless variable/class names etc).

As far as I know this is not supported by standard JVM. But you can do the following. Separate your application into 2 parts. First will not be encrypted. It will be a simple loader that will instantiate the rest using custom class loader. This class loader will get Classes as arrays of bytes, decrypt and load them.

if you don't want to provide an access to the class files inside the jar, why should you supply your jar with the application?
It feels like your question is kind of wrong conceptually...
If you need some custom way of loading the classes, consider to use custom classloader.

if you are packaging in jar -> just rename it to jarname.ABCD or any misleading extension or even take off the extension, and accordingly specify the jar name in your application.

i prefer jCrypt!
It is a simple tool where you can crypt the classes(and ressources)

Related

Obscuring JNI Code From End Users in Android

I've written a bunch of android JNI code that I want to make into a library for a customer. Obviously, I don't want the customer to be able to see my JNI code. Is there a way I can include just the so file in a library project for them?
I've tried just using System.loadLibrary(<library>); but I get an Unsatisfied Link Error every time.
One thing that's worked, is I've just compiled my project and deleted all the c files. I'm still able to use the .so file, but if I do a make clean, it deletes my so file and there's no way to recover it without the source.
In short, what I want is to be able to compile an so file on my own, and give it to my customer with some java code that interfaces with it. I don't care if they see the java 'wrapper' source but I don't want them to be able to see the JNI code. I also want them to be able to treat this library as they would any other (ie make cleans don't wreck it).
Thanks!
Is there a way I can include just the so file in a library project for them?
Package an AAR containing the libraries, and host the AAR as an artifact for your customers. See my CWAC-AndDown library for an example. The AAR will contain your .so files for whatever architectures that you are supporting, plus a JAR of the compiled Java code that provides your Java API to the native code.
I also want them to be able to treat this library as they would any other (ie make cleans don't wreck it).
Well, by definition, make clean requires source. It also requires a makefile, which presumably you will not distributing, since that's useless without the source.

Download Java Class File & Run?

Okay, so pretty much I'm trying to add security to my Java class file. I don't want it to get decompiled. So what I've done is created a login system where the java app checks it through a web request. If the login information is correct then it will run the script. However, I want to further improve security and have the class file hosted online.
How can I make it download & run the online hosted file?
Also, when the app/script stops running or it's closed the .class file is deleted.
I'd prefer where it did not have to download the file, just get from an online server and compile/run.
Let's go through the things you have done, and the things you are proposing to do and see if they will really work:
Asking for a password. This is easily to defeat:
Capture the classfile.
Decompile it.
Identify the place where it makes the remote call does the login check, and checks the response.
Modify the bytecodes to remove all of that.
Rather than installing the class file, download it on demand and delete it when it finishes. Also easy to defeat.
Capture network request made to download the file.
Replay the request using (say) curl or wget and capture the downloaded class file.
Proceed as above.
And variations are relatively easy to defeat too:
Obfuscation can always ultimately be defeated by manual decompilation and/or running the bytecodes using a debugger.
Downloading using one-time key or something can be defeated by reverse engineering the procedure and extracting the one-time key ... before it is used.
Encrypting the bytecodes can defeated because the JVM has to have the bytecodes in decrypted form at some point. So the means of decryption of the bytecodes must be embedded in code ... that can be reverse engineered.
The bottom line is that it is impossible to prevent a skilled and determined person from defeating security schemes that depend on keeping things secret from a user who controls his / her own execution platform.
The best you can hope to do is stop low-skilled attackers, and slow down skilled ones. You need to ask yourself ... is it really worth the effort?
(Note: you have the same problem no matter what implementation language you use.)
Create a new URLClassLoader (the "default" Java classloader) and point it at wherever you saved the file:
// the directory where you're saving the .class file
File tmpDir = new File("/tmp/yadda/blah/");
ClassLoader cl = new URLClassLoader(new URL[] { tmpDir.toURI().toURL() }, Thread.currentThread().getContextClassLoader());
Class<?> cls = cl.loadClass("SuperSecretClass");
// use reflection to instantiate cls, call methods, etc.
(Passing in the parent class loader might not be necessary in a non-webapp, but I'm too lazy to test that detail. Using the thread's classloader explicitly will work one way or the other.
This assumes that your secret class is not in a package, if it is you'll have to create the appropriate directory structure inside the temporary directory and point the classloader at the root of the package tree, as usual.
Also: this sort of security-by-obscurity sounds like a bad idea. You're still downloading the file, if it's over an unsecured connection a determined attacker can sniff it, and there's still the period of time during which it's on disk. You could create a completely custom ClassLoader that directly reads the stream, but even the class file could probably be recovered with a little more effort. (Like pointing a debugger at your main app and intercepting stream reads.) The javadoc for ClassLoader provides an example of how to do this.

Reading bytecode from unloaded classes in external jarfiles

In my Java application, I wish to read bytecode contents from class files that aren't actually loaded, in jar files which also aren't loaded. As in, I need to be able to take any given jarfile, and find all classes inside it, ideally. So take the following situation:
My application (which is kind of a library), is asked to 'check' a certain jar at whatever path, and is provided various patterns provided by the application using my library to find similarities (such as constant pool similarities). Therefore my library needs to go through all the jars in a class file. Obviously I could make it hardcoded or loaded from a file, but I'd much rather have it so that I can go through the bytecode of all the files in a jar to match them.
You should use the JarFile API and iterate over the files in it.
It shouldn't be hard to do. This article might be a good start.
And as for the bytecode you could just treat each (uncompressed) class file as a byte array and calculate a hash, maybe an MD5 hash of each file and compare it to previous hash.

Can you access items inside a jar using File

I have some files inside a jar which I would like to access in Java using a File object rather than as a stream. Is it possible to do this?
Look at JarFile.
java.io.File is an abstraction from os specific handling of files. If you use java.io.File in your code, the code should run on all Java platforms.
The Jar is not a os file system. So it makes no sense to apply java.io.Files from the Java core classes.
I don't want to say it is not possible. Maybe it has sense for certain application and there is a library for that kind of abstraction.
You can also access it as a URL with a "jar:" prefix, but that's not a File object either, so I guess that doesn't meet the restriction.
Why do you have to access it as a File? This seems like asking, "Is there any way I can add two numbers without using the plus operator?" Maybe you can, but why do you not want to do it the easy way?

Real runtime method names despite obfuscation?

Is there any way to query the name of the current method if you've obfuscated your code? I'm asking because there are times when I want to log a message with the executing method as a prefix.
Just add the method name directly to the string you are outputting. If you get the name of the current method via reflection, it will be the obfuscated name. If it was not this way, anybody would be able to figure out the original method, defeating the obfuscation (or dramatically hampering it).
Alternatively, obfuscation tools are supposed to be able to output their own obfuscation logs so you can write a tool to translate your application's obfuscated logs into something human-readable.
Of course, once you get there, development versions of your application could include the ability to access their own obfuscation logs and translate the result of reflection before they output logs.
You can have obfuscation logs on the file system, as an application resource in the jar file or download them from a remote server.
If you only keep decrypted obfuscation logs in your application memory, the VM sandbox is supposed to keep them fairly safe.
Please reconsider why you want to obfuscate. The things an obfuscator obfuscates is frequently those useful for debugging.

Categories

Resources