I was looking for an encryption package for GWT.  A client had some mildly private information that they wanted to encrypt in transmission.  Now, of course, this is ultimately futile.  Anyone who wants to get at this information can, because we send the source code (however obfuscated) that decrypts the information to the client.  To borrow Corey Doctorow’s words, the attacker is also the recipient.  But, sometimes just making getting the information inconvenient is good enough.

I looked at a couple of encryption options.  There’s are a couple of nice javascript libraries that do encryption: Gibberish-AES and javascript.crypto.library, but they hav no GWT hooks (and javascript.crypto.library is released under the AGPL which has some unclear legal ramifications).

However, there is a project from about two years ago that does Triple DES encryption and is written in pure GWT.  It’s even called gwt-crypto.  Unfortunately, it hasn’t been maintained recently.  I was able to download the files, apply a fix (for issue #1) and move some files around in such a way that it works.

Here’s how you use it:

on the server:
TripleDesCipher cipher = new TripleDesCipher();
cipher.setKey(Constants.GWT_DES_KEY);
try {
enc = cipher.encrypt(String.valueOf(value));
} catch (DataLengthException e1) {
e1.printStackTrace();
} catch (IllegalStateException e1) {
e1.printStackTrace();
} catch (InvalidCipherTextException e1) {
e1.printStackTrace();
}

On the client, make sure you inherit the module:
<inherits name='com.googlecode.gwt.crypto.Crypto'/>
Then:

TripleDesCipher cipher = new TripleDesCipher();
cipher.setKey(Constants.GWT_DES_KEY);
String dec ="";
try {
dec = cipher.decrypt(enc);
} catch (DataLengthException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (InvalidCipherTextException e) {
e.printStackTrace();
}

I just use a constant DES key, which is not all that secure.  I’m sure you could do something more secure like hashing the request time, filename and some other secret key, but you need to make sure that both the server and the client agree on the key, otherwise you’ll not be able to decrypt the info.

Update 6/13: I got permission from the project owner to update the google project, so I’ve done that.  You can download the new gwt-crypto jar there.

The modified gwt-crypto jar file is here.  I’m hoping the administrator will let me at least check in the changes I’ve made so that it works on GWT 1.5.3 (can’t speak for GWT 1.6).

Technorati Tags: , ,

12 thoughts on “GWT encryption options

  1. Jerry says:

    Hi, What value did you pass for the constant.GWT_DES_KEY

    cipher.setKey(Constants.GWT_DES_KEY);

    I am trying to implement a encrypt/decrypt mechanism using your solution
    thanks.
    j

  2. moore says:

    Hi Jerry,

    You need to pass in a 24 byte array:

    public static final byte[] GWT_DES_KEY = new byte[]{
    (byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,
    (byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,
    (byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,};

    Obviously, change this to be random numbers, not all ones.

  3. Jerry says:

    Hi Moore,

    Thank you very much for your reply, i was able to integrate the gwt-crypto library in my project it works very well without any issues.

    Thanks for sharing a great encryption library.

    Regards,
    Jerry.

  4. fred says:

    hi,

    i’m using gwt 2.3 and gwt crypto.

    when i’m encrypting a pass on the client side everything works fin but when i try to decrypte it on the server side, i get an exception

    java.lang.NoClassDefFoundError: com/googlecode/gwt/crypto/bouncycastle/DataLengthException

    Caused by: java.lang.ClassNotFoundException: com.googlecode.gwt.crypto.bouncycastle.DataLengthException

    does anyone have any idea why?

    thanks,

  5. fred says:

    apparently it bugs event when i don’t encrypt data at all;

    it must be a problem whit the version (maybe?)

  6. moore says:

    Hi Fred,

    Did you ensure that the gwt-crypto jar file is in your server side classpath?

  7. DFB says:

    Hello Dan,

    I was looking for exactly this information. Thanks for sharing it.

    I implemented this in my GWT / GAE based app and initially it seemed to work perfectly. However, later I discovered that my app stopped working when accessed from within my company’s network (firewalled, of course). Note that the app is deployed outside the firewall on GAE. I can still access the app outside of the company network. Before implementing this encryption/decryption, I never had such a problem.

    In the GAE log, I’m seeing an exception java.security.AccessControlException: access deniled. Do you know if there’s any chance that this can blocked by a firewall?

    I’ll appreciate any help that you can provide.

    Thanks again.

  8. DFB says:

    To add more to the above message, I’m using Guice injector to instantiate the class on the client that instantiates the ‘cipher’. The following is the ‘trimmed down’ trace of the exception (I don’t want to flood your comments section by posting the complete trace):

    com.google.inject.internal.util.$FinalizableReferenceQueue : Failed to start reference finalizer thread. Reference cleanup will only occur when new references are created.
    java.lang.reflect.InvocationTargetException
    at com.google.appengine.runtime.Request.process-08f6a071018918d2(Request.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:43)
    at com.google.inject.internal.util.$FinalizableReferenceQueue.(FinalizableReferenceQueue.java:124)


    com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:103)
    at com.google.inject.Guice.createInjector(Guice.java:95)
    at com.google.inject.Guice.createInjector(Guice.java:72)
    at com.google.inject.Guice.createInjector(Guice.java:62)
    at com.dfb.pmproc.server.guice.PMProcGuiceServletContextListener.getInjector(PMProcGuiceServletContextListener.java:12)
    at com.google.inject.servlet.GuiceServletContextListener.contextInitialized(GuiceServletContextListener.java:45)


    at java.lang.Thread.run(Thread.java:636)
    Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission modifyThreadGroup)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:355)
    at java.security.AccessController.checkPermission(AccessController.java:567)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:315)
    at java.lang.Thread.init(Thread.java:349)
    at java.lang.Thread.(Thread.java:436)
    at com.google.inject.internal.util.$Finalizer.(Finalizer.java:92)
    at com.google.inject.internal.util.$Finalizer.startFinalizer(Finalizer.java:81)
    … 49 more

  9. DFB says:

    Another update .. the exception I mentioned is thrown even when the app is working (outside the firewall). So that seems harmless. The problem seems to be with the firewall now. Sorry for the multiple posts. Thanks.

  10. DFB says:

    I’ve fixed the exception, and created 2 different versions of the app – one with encryption and the other without. I used a flag to turn the encryption on/off. When encryption/decryption disabled, the app works fine inside the firewall. With encryption/decryption enabled, it doesn’t load at all inside the firewall.

    Thanks.

  11. ChanceLai says:

    Hi,Moore.
    I’m so bad in the encryption.
    Why the data is so big after used yuu method?
    And which implement can compress it?

Comments are closed.


© Moore Consulting, 2003-2017 +