Protecting .class files.

I am in the stage of requirements for creating a Java EE application that will most likely run on the GlassFish / JBoss backend (it doesn't matter now). I know that I should not think about architecture during requirements, but it is impossible not to begin to imagine how all components will be combined :-)

Here are some tough, inflexible client-side requirements:
(1) Client application will be Swing box
(2) The client is free to download, but will use the subscription model (this requires a login mechanism with authentication / authorization on the server side, etc.)
(3) Yes, Java is the best solution to solve this problem for reasons beyond the scope of this post.
(4) Client .class files need protection against decompilation

This last (fourth) requirement is the basis of this post.

I'm really not worried that someone is really decompiling and getting my source code: after all, it's just a Swing control driven by some easy business logic.

I am worried about the scenario when someone decompiles my code, modifies it to use / attack the server, recompile and run it.

I foresaw all kinds of unpleasant solutions, but did not know if this was a common problem with a common solution for Java EE developers. Any thoughts?

Not interested in code obfuscation methods

Thanks for any input!

+6
java security
source share
5 answers

I am here to bring you bad news. You cannot stop it.

I dug deep into this one time. At minimum levels, the JVM Classloader should receive an unencrypted byte stream, which is a class file. You cannot change this by replacing the JVM with your own code. In addition, there is a hook that allows you to view the stream of bytes (copy, etc.). No matter what you do at higher levels, the JVM will always reach that point and allow access to your class file. After receiving the class file, it can be decompiled. Obfuscation methods and tools can slow it down or make it difficult, but they also cannot stop it.

I highly recommend that you protect your server using proven and reliable security methods. Do not put secret sauce in what you give to the client. They will somehow manage this if they are defined enough.

+5
source share

You should assume that the code will be decompiled and used to use / attack the server.

Just trust what the server does.

+9
source share

I see this as a general problem with “strong v. Weak” cryptography: if knowledge of the algorithm is sufficient to discredit the message (ie your login), cryptography is weak.

How to use something like OAuth instead? Thanks to a one-time authentication process with the server, the client application receives tokens, and the server can always cancel authorization for any given client if it is ever needed.

Also note that authentication does not replace authorization. Just because your system thinks it knows who someone is, this does not mean that they should have the right to do whatever they want. You also need to deploy good access controls, such as those provided by JAAS or Spring Security, and associate this with authentication. The first check of any call from the client is performed for authentication, the second is whether a particular client is allowed to make a call in the first place.

No matter what you do, your server should only allow calls based on the authorization granted to the user.

+3
source share

Use strong server authentication, do not store user names, passwords or encryption keys in the application, and then, as Rekin comments, I don’t see that your server’s security might be interrupted in your code.

If you absolutely need to encrypt messages (not like the requirement), use SSL or any public-key cryptography.

+1
source share

I have a “think out of the box” solution for point number 4.

I assume that your application has network access when it connects to the Internet for authentication ...

  • You have a bunch or "jar" files with classes in them. The only difference is that classes are encrypted using a symmetric key.
  • When the application starts, the application starts on the network, receives authentication and retrieves the key over a secure connection (for example, SSL).
  • Then you load all the encrypted files into memory and decrypt them.
  • Then you create a custom classloader and load the decrypted class into the classloader using ClassLoader.defineClass
  • Then you are good to go!

This is not a concrete way to do something and, as I said, it is out of the box. But making it a little harder to steal your code. But, as other posters said, you cannot hide secrets in your code, which is on the client side.

0
source share

All Articles