Distribute java program with security

Discussion in 'Java' started by Kevin, Jun 15, 2006.

  1. Kevin

    Kevin Guest

    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
    Kevin, Jun 15, 2006
    #1
    1. Advertising

  2. Kevin

    Dag Sunde Guest

    Kevin wrote:
    > 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?


    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.

    --
    Dag.
    Dag Sunde, Jun 15, 2006
    #2
    1. Advertising

  3. Kevin

    ddimitrov Guest

    Kevin wrote:
    >
    > 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
    > 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.
    >
    > 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
    ddimitrov, Jun 15, 2006
    #3
  4. Kevin

    Chris Uppal Guest

    Kevin wrote:

    > 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.


    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
    Chris Uppal, Jun 16, 2006
    #4
  5. Kevin

    Chris Uppal Guest

    ddimitrov wrote:

    > 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
    Chris Uppal, Jun 16, 2006
    #5
  6. Kevin

    Kevin Guest

    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!~
    Kevin, Jun 16, 2006
    #6
  7. Kevin

    IchBin Guest

    Kevin wrote:
    > 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!~
    >


    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-)
    IchBin, Jun 16, 2006
    #7
  8. Kevin

    Guest

    Kevin wrote:
    > 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?


    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
    , Jun 17, 2006
    #8
  9. Kevin

    Chris Uppal Guest

    IchBin wrote:

    > 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, Jun 17, 2006
    #9
  10. Kevin

    Chris Uppal Guest

    Kevin wrote:

    > 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
    Chris Uppal, Jun 17, 2006
    #10
  11. Kevin

    Guest

    ddimitrov wrote:
    > Kevin wrote:
    > >
    > > 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
    , Jun 18, 2006
    #11
  12. Kevin

    ddimitrov Guest

    wrote:
    > ddimitrov wrote
    > > 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
    ddimitrov, Jun 18, 2006
    #12
  13. Kevin

    Guest

    ddimitrov wrote:
    > 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.)


    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
    , Jun 19, 2006
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. bigbinc

    distribute java apps

    bigbinc, Nov 26, 2003, in forum: Java
    Replies:
    5
    Views:
    393
    Roedy Green
    Nov 26, 2003
  2. Replies:
    1
    Views:
    1,146
    Martin Gregorie
    Apr 2, 2006
  3. Darius
    Replies:
    4
    Views:
    368
    Mark McIntyre
    Apr 13, 2005
  4. Dobedani
    Replies:
    5
    Views:
    1,456
    Dobedani
    Jun 7, 2007
  5. January Weiner

    Best way to distribute program with modules

    January Weiner, Mar 3, 2008, in forum: Perl Misc
    Replies:
    1
    Views:
    80
    Ben Morrow
    Mar 3, 2008
Loading...

Share This Page