2009-07-10

GWT and AES decryption

I’ve been working on a simple GWT application which had to decrypt some content in the browser. The requirement was that this should happen in the browser – as close to the end user as possible.

The first solution I considered was to use Java code which then would be generated into JavaScript with the GWT compiler. I couldn’t use the built in support in Java since these classes isn’t supported by the GWT compiler, but I thought I might find an implementation which could be used. After some research I found this comment and the specifically the first point:

virtually all crypto libraries out there,… to asymmetric 
(RSA, DSA, 'public/private keypairs') rely heavily on register
looping; the idea that the maximum value an integer field will
hold + 1 'loops around' silently to the minimum value.

javascript numbers do not behave that way (they upgrade
themselves silently to doubles) - and GWT's 'ints', for
reasons of speed, aren't objectified stuff that
software-matically does integer math, they are just translated
to javascript numbers. Hence this looping never occurs, and all

those libraries get confused, and they don't work. You're FAR
FAR better off finding a proper chunk of code designed for
javascript specifically, and wrapping that using JSNI.

This certainly made me look the other way which was to embed JavaScript implementation of the AES algorithm. We had some requirements to the algorithm implementation:


  • Support for 256 bit key lengths

  • Support for salt

  • Cipher Block Chaining

  • Support for initialization vector

  • Handle PKCS-7 padding

After some trial with several implementations we finally got the pidCrypt library working with the content encrypted by our WPF .NET client. It is hosted on SourceForge and the team has been really responsive to questions regarding challenges that I experienced.

In order to get this to work with GWT I had to do the following:

Add the JavaScript to the project

I added the following JavaScript files pidcrypt.js, pidcrypt_util.js, aes_core.js, aes_cbc.js and md5.js to the project (src/main/webapp).

Make those JavaScripts available to the GWT applicaiton

I had to declare the scripts in my GWT application configuration:

<script src="pidcrypt.js" />
<script src="pidcrypt_util.js"/>
<script src="md5.js" />
<script src="aes_core.js" />
<script src="aes_cbc.js" />
Wrap those JavaScript calls with native methods

In order to call those JavaScripts from my "regular Java code" (the Java code which gets compiled to JavaScript), I had to wrap the JavaScript calls with native methods:

public static native String Decrypt(String encryptedText, String key)
/*-{
var aes = new $wnd.pidCrypt.AES.CBC();
var iv = '4857487548754874587549889898';

aes.initByValues(encryptedText, key, iv, {nBits:256, A0_PAD:false});

return aes.decrypt();
}-*/;

With this in place, I was able to decrypt some of the content which our .NET client had encrypted.

2009-07-03

Building GWT application with Gradle

I wanted to check out Gradle in a small GWT application that we build for a very specific purpose. The Gradle version I've used is 0.61. Gradle has a plugin concept, but I haven't seen any GWT plugin for Gradle. The setup ended up being rather easy.

I defined a task which used ANT's Java task:

task gwtCompile << {
created = (new File(gwtBuildDir)).mkdirs()
ant.java(classname:'com.google.gwt.dev.Compiler', failOnError: 'true', fork: 'true') {
jvmarg(value: '-Xmx184M')
arg(line: '-war ' + gwtBuildDir)
arg(line: '-logLevel INFO')
arg(line: '-style PRETTY')
arg(value: 'me.trond.app.MyApp')
classpath {
pathElement(location: srcRootName + '/' + srcDirNames[0])
pathElement(path: configurations.compile.asPath)
pathElement(path: configurations.gwtCompile.asPath)
}
}
}


If you look at the classpath elements I've included a special configuration called gwtCompile. I had to define my own configuration:

configurations {
gwtCompile
}


This also had to be reflected in the dependencies:

dependencies {
...
gwtCompile (
[group: 'com.google.gwt', name: 'gwt-user', version: '1.6.4'],
[group: 'com.google.gwt', name: 'gwt-dev', version: '1.6.4', classifier: 'windows']
)
}


Since I use the war plugin for gradle I had to make sure that gwtCompile task got called before packaging up the war file:

war.dependsOn gwtCompile


Also ensured that the result of the gwtCompile got included in the war file:

war {
//Adds the JavaScript and resources compiled by the GWT compiler
fileSet(dir: file(gwtBuildDir) )
}