Java Forum / General / June 2006
Distribute java program with security
Kevin - 15 Jun 2006 22:36 GMT Hello all,
I have a question of how to distribute the java programs (applications) in a proper way, hope anyone can have some practical suggestion. Thanks.
The issues are:
1) we don't want the end user to be able to de-compile our program. So distribute the .jar is a bad choice. By the way, we are using JBuilder, the JBuilder's "build to .exe" is also a bad choice since I found it simply wrap the .jar (just change the .exe back to .zip will be able to see all the class files).
2) since our application may need some pretty frequent update, it would be nice if the distribution method can help it as well (it would be hard to keep the list of users who use the program, and email them the update). PS: the java program is about 2-4M size.
Under these two requirement, what methods are preferred?
I hear java has a WebStart, does it downloads and saves / cache the .jar files to the client's PC?
Thanks a lot.
Kevin
Dag Sunde - 15 Jun 2006 23:18 GMT > Hello all, > [quoted text clipped - 19 lines] > I hear java has a WebStart, does it downloads and saves / cache the > .jar files to the client's PC? Yes... That's one of the main thingys about JWS. It checks taht everything is ok on the client to run it, download the whole caboodle and caches it.
The next time, it just check if anything new is on the server. If not, it just run from the previous DL. If it is anything new/updated, it downloads that and start.
So, if you just realise that your app will, and can be "de-compiled" if someone really wants to, and start ignoring it.... JWS is the way to go.
 Signature Dag.
ddimitrov - 15 Jun 2006 23:25 GMT > 1) we don't want the end user to be able to de-compile our program. So > distribute the .jar is a bad choice. I can think of a couple of ways to do this, raging from easy and unobtrusive to crazy paranoid:
1. Use obfuscation for release builds. There are free obfuscators like RetroGuard, which will not prevent the potential hacker from decompiling, but are going to significally increase the effort. Cons: the stacktraces will be garbled, so you need to use a demangler every time the client sends you log file with stack trace. Releasing patches is cumbersome.
2. Use custom class loader. Encrypt the classes before you create the jar (there are many schemes you can use - i.e. you can use password based encryption and calculate the pass as a hash of the package name). You'd need a custom bootstrapper with class loader which decripts the classes on the fly. Cons: the bootstrapper is a weak link - you have to combine this with 3 in order to be really effective.
3. Use custom native JVM launcher (check the Invocation API), decoding the encrypted bootstrapper on the fly, also checking for suspicious activity (like all the process threads being suspended for more than 10 seconds).
This way you have raised the difficulty of decompiling the Java code rto that of decompiling native code (which is perfectly doable by the way - see IDA Pro )
> 2) since our application may need some pretty frequent update, it would > be nice if the distribution method can help it as well (it would be [quoted text clipped - 3 lines] > I hear java has a WebStart, does it downloads and saves / cache the > .jar files to the client's PC? Your requirement sounds like a good candidate for Web Start. Yes, it downloads and caches jars. I have never used it myself, but I plan to very soon.
As far as I understand, most of the major complains about JaWs revolve around the auto-update functionality. What we plan is to use different links to the different application versions and publish the latest and greatest link to a common web page. This also has the advantage that the user can back out or compare versions easily.
An installer might be a good idea if you have problems converting your app to JaWs. I'd reccomend IzPack + Jaunch4J, but there are other installers that would work just a s well.
Regarding the distribution, if you use Maven, you can keep track of your user list inside your pom and then use a simple script to extract the addresses and send the update email.
cheers, Dimitar
Chris Uppal - 16 Jun 2006 14:26 GMT > 2. Use custom class loader. Encrypt the classes before you create the > jar (there are many schemes you can use - i.e. you can use password > based encryption and calculate the pass as a hash of the package name). > You'd need a custom bootstrapper with class loader which decripts the > classes on the fly. Cons: the bootstrapper is a weak link - you have to > combine this with 3 in order to be really effective. I haven't checked this myself, but a previous poster on a similar subject asserted that putting a breakpoint on the native DefineClass() function will trap the bytecode after it has been decoded and before it is used. One could do something similar with the JNMTI interfaces, or by creating a "dummy" JVM.DLL.
As Dimitar noted, you can make this technique more robust by using a custom launcher too.
-- chris
Kevin - 16 Jun 2006 17:49 GMT So, for these two methods: 1) obfuscation 2) convert java to real binary code (for me, we need to run it on MS Win)
which software tools do you guys recommend most? ---- In terms of 1) how hard it make the un-complie difficult, 2) less harm of the run time speed.
It can be free ones, or commercial ones.
Thank you a lot!~
IchBin - 16 Jun 2006 18:38 GMT > So, for these two methods: > 1) obfuscation [quoted text clipped - 8 lines] > > Thank you a lot!~ 1 - Proguard (http://proguard.sourceforge.net/) This is a java shrinker, optimizer, and obfuscator. I am really happy with this free product.
2 - JSmooth (http://jsmooth.sourceforge.net/) is a Java Executable Wrapper
Thanks in Advance... IchBin, Pocono Lake, Pa, USA http://weconsultants.servebeer.com/JHackerAppManager __________________________________________________________________________
'If there is one, Knowledge is the "Fountain of Youth"' -William E. Taylor, Regular Guy (1952-)
Chris Uppal - 17 Jun 2006 11:31 GMT > 2 - JSmooth (http://jsmooth.sourceforge.net/) is a Java Executable Wrapper But note that JSmooth is /only/ a wrapper -- it just replaces java.exe (or javaw.exe), the bytecode is still there in exactly the same form.
-- chris
Chris Uppal - 17 Jun 2006 11:33 GMT > which software tools do you guys recommend most? ---- In terms of 1) > how hard it make the un-complie difficult, 2) less harm of the run time > speed. > > It can be free ones, or commercial ones. For compilation, I've already mentioned one name (the only reasonable one as far as I know). For obfuscation there are many choices, I can't recommend any. The commercial ones claim to be better than the free ones, and -- who knows -- maybe they are telling the truth...
-- chris
ldv@mail.com - 18 Jun 2006 07:59 GMT > > 1) we don't want the end user to be able to de-compile our program. So > > distribute the .jar is a bad choice. > > I can think of a couple of ways to do this, raging from easy and > unobtrusive to crazy paranoid: [skip]
> 2. Use custom class loader. Encrypt the classes before you create the > jar (there are many schemes you can use - i.e. you can use password > based encryption and calculate the pass as a hash of the package name). > You'd need a custom bootstrapper with class loader which decripts the > classes on the fly. Cons: the bootstrapper is a weak link - you have to > combine this with 3 in order to be really effective. Here is why this won't work at all:
http://www.javaworld.com/javaworld/javaqa/2003-05/01-qa-0509-jcrypt.html
LDV
ddimitrov - 18 Jun 2006 14:47 GMT > > Cons: the bootstrapper is a weak link - you have to > > combine this with 3 in order to be really effective. > > Here is why this won't work at all: > > http://www.javaworld.com/javaworld/javaqa/2003-05/01-qa-0509-jcrypt.html I thought I made it clear in my first post, but since everybody feels obliged to basically repeat my last sentence from point 2, maybe I should go into more detail.
First things first: if you are going to run this program on your client's machine and your client is determined (and sufficiently technically advanced) to reverse engineer it, there is no way to stop him. Deal with it. If it is really an issue, then think about implementing the critical parts of your app as a remote service (be it RMI, web service or plain HTTP requests). Mind that if you charge your customers fixed price or subscription price and do not limit the number of calls they can make per second, they can make a clean-room implementation of your service, which from business POV is just as bad as reverse engineering (i.e. they stop paying).
Fortunately, it is very easy to make the reverse engineering if not imposible, then unreasonably hard. As everybody else said, the obfuscators are the first line of defence - they make your code much harder to decompile and as bonus it will usually get smaller and faster due to the shorter symbolic names and some aggressive optimizations that the compilers are not allowed to make because of the JLS.
The next line is the encryption/signing. Encryption is good especially when the code goes through third parties. On the other hand, obviously you need some code to decrypt what is encrypted. As I said, this code is the weak point of any scheme which relies on encrypted classloaders. So what do we gain, you might ask?
What we gain is that now we have to cover only one spot and if we protect it well enough, we can stop worrying about our bytecode being visible in the wild. What we can do in this case is to implement the bulk of this decrypting classloader in native code, using native code the protection techniques which we all undoubtedly know. I've mentioned some of them, like comparing the API entry points of well known platform functions, looking at the timer to check that there are no unreasonable time-lapses and so on. We can even use a dongle, to make sure that the user has not tampered with the system timer. (essentially that was 'point three' from my first mail.)
Having done this, we have increased the dificulty of reverse engineering our Java code to that of any native code. Still it's doable. There are hardware protocol analyzers which can replay what went through the buss and take snapshots of the whole system memory without stopping the CPU. There are enough smart people who can dissasemble your carefully crafted native code if nessesary make fake dongles and they are experts in this kind of stuff, just as some people are in protecting the software.
The key here is to make the reversing not impossible, but unfeasible. It's all about the balance between the price of the application, effort to reverse, audience (nobody reverses software for cow milkers), popularity and probably many other factors.
It is a good idea to decide on a fixed time that you are willing to invest into protection (that is research + implementation). Otherwise, you might spend more time working on the protection than on your application code.
All that said, IMHO the best tradeoff is a simple obfuscator plus password based encryption (no native launcher). It's easy to implement and will keep away a good part of the wannabe hackers. It's not worth trying to stop the other 10% - they are smarter than me anyway.
cheers, Dimitar
ldv@mail.com - 19 Jun 2006 04:42 GMT > What we can do in this case is to implement the > bulk of this decrypting classloader in native code, using native code [quoted text clipped - 4 lines] > sure that the user has not tampered with the system timer. (essentially > that was 'point three' from my first mail.) It does not matter how do you implement the decrypting classloader. As some point the _decrypted_ bytecode must be fed to the JVM, where it is very easy to intercept. Here is an excerpt from the JavaWorld article I referred to in my previous post:
"All ClassLoaders have to deliver their class definitions to the JVM via one well-defined API point: the java.lang.ClassLoader.defineClass() method. The ClassLoader API has several overloads of this method, but all of them call into the defineClass(String, byte[], int, int, ProtectionDomain) method. It is a final method that calls into JVM native code after doing a few checks. It is important to understand that no classloader can avoid calling this method if it wants to create a new Class.
The defineClass() method is the only place where the magic of creating a Class object out of a flat byte array can take place. And guess what, the byte array must contain the unencrypted class definition in a well-documented format (see the class file format specification). Breaking the encryption scheme is now a simple matter of intercepting all calls to this method and decompiling all interesting classes to your heart's desire (I mention another option, JVM Profiler Interface (JVMPI), later)."
LDV
Chris Uppal - 16 Jun 2006 12:56 GMT > 1) we don't want the end user to be able to de-compile our program. So > distribute the .jar is a bad choice. By the way, we are using JBuilder, [quoted text clipped - 6 lines] > hard to keep the list of users who use the program, and email them the > update). PS: the java program is about 2-4M size. Given (2) why are you so worried about (1) ? Probably the best defence there is against people cracking your software is if the cracked versions quickly become out-of-date.
Anyway, there are many Java obfusators available, both free and commercial. Perhaps you could use one of those.
A completely different approach would be to use a native compiler like Escelsior Jet.
-- chris
ldv@mail.com - 17 Jun 2006 09:42 GMT > Hello all, > [quoted text clipped - 16 lines] > > Under these two requirement, what methods are preferred? Compile your program to a native code EXE using either Excelsior JET (http://www.excelsior-usa.com/jet.html) or GCJ (http://gcc.gnu.org/java/) and use a native Windows setup generator such as InstallShield to manage automated updates.
> I hear java has a WebStart, does it downloads and saves / cache the > .jar files to the client's PC? Yes, exactly.
See also the article at http://www.excelsior-usa.com/articles/java-to-exe.html for links to reference materials and tools
LDV
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|