3

I'm writing a piece of software that is distributed as a JAR file. Currently, this JAR file can be tampered with to retrieve and save another file that our server transmits via URLClassLoader, be decompiled, and find various things in our code that should remain private for the security of the clients using it. Basically, I want to implement a way to check if the original JAR is tampered with. I know this is paradoxically impossible by implementing a check for validity of a SignedObject in the original class due to the nature of Java being able to be decompiled, but is there some other way that I can determine if code has been tampered with in the original file? This check can happen via an intermediary class that is downloaded to check for validity, or any other means that will be guaranteed to work. I've been sitting here all day trying to come up with a solution to this problem. Any help is welcomed.

Clay Freeman
  • 533
  • 5
  • 17
  • About the only thing I can think of using some kind of file hash (MD5) which will tell if the Jar file has being changed (ie added to or removed from or modified, but not if it has begin opened). You could keep this information on a server some where. When the Jar is to be loaded, you could check back with the server to determine if the MD5 matches (don't ask for it from the server, send it to the server). You would also expire a Jar so would need to be re-downloaded again after a period of time... – MadProgrammer Jul 17 '13 at 23:06
  • I see a problem with this. The original JAR can be modified to save the JAR that is downloaded, look at how the checks are made, and then recompile it to disregard the checks for validity, and we are in the same boat again. – Clay Freeman Jul 17 '13 at 23:13
  • When you application loads the Jar, it needs to be performing the validation. Yes, at some level it can be broken, but that's a lot of work for non-technical people. If the Jar is talking back to base (ie requesting data from the server), it could also pass back a key, which you can expire at some time in the future, requiring a new Jar to be downloaded (with a new key). If you are class loading the Jar's yourself, you could encrypt the Jars/classes – MadProgrammer Jul 17 '13 at 23:15
  • The key can be compromised and sent to the server statically from a modified JAR. This needs to be impossible to bypass. I don't care if the casual redneck can't break validation. – Clay Freeman Jul 17 '13 at 23:24
  • Yes, anything you do could be compromised, so what are you going to do. Unplug from the internet? You could simply running the application as web application, but there are ways to breach those to. You won't ever, as you stated, find an absolute solution. – MadProgrammer Jul 17 '13 at 23:29

1 Answers1

2

This is theoretically and practically impossible. The verification of jars occurs on the client side. Any cryptography is not presented to you in a verifiable fashion, and you trust that the client offers any crypto.

Even if you were to request arbitrary bytes from the jar file itself for verification, the evil user may configure for bytes to be taken from a good jar but presented by bad code.

You can use a cryptographic proof to ensure the other side has data, but making sure that it only has that copy/revision/version of that data is impossible. A determined attacker can feed you any lies as he can claim in any verification that he has the valid jar.

In short, presence of correct data does not imply exclusive presence of same.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
  • I discovered the same thing. I ended up using a socket to deliver the JAR when I trigger it to be delivered manually. This isn't the best solution, but it works for now. – Clay Freeman Jul 18 '13 at 03:40