Sunday, October 4, 2015

Grails-JavaScript Encrypted Communication - Part I

For adding new feature to my framework RIRA I should have encrypted communication between client (page) and server(controller) for sensitive information and actions like username and password on login or setting new password. So the basic plan was having RSA (private/public key) encryption of form data in page by javascript and decrypt and use them in controller side.

On testing, troubleshooting and studying best practices for this purpose I found that RSA supposed to be used for encrypting short length data, something like a password or key and not the whole form data. So the best practice was encrypting data by AES with a random key, then encrypt that random key with RSA public, and do vice versa on server side.

For the server side I chose the bouncycastle java lib as provider since it is supporting PEM key reading (parsing), because I want to make it easy for the admin of the application to generate and change the key simply, by something like openssl command line in this case. Here is the method to read PEM file:

static KeyPair getKeyPair(String pk, char [] password) {
 PEMParser pemParser = new PEMParser(new CharArrayReader(pk.toCharArray()))
 Object object = pemParser.readObject()

 PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password)
 JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC")

 KeyPair kp
 if (object instanceof PEMEncryptedKeyPair) {
  kp = converter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decProv))
 } else {
  kp = converter.getKeyPair((org.bouncycastle.openssl.PEMKeyPair) object)
 }
 kp
}

For security the password must be passed and processed as char [] instead of String object, since String is seen as one object and may be accessed before garbage collection.

The first challenge appear here that PEMParser (Thhe deprecated and removed class was PEMReader) class that is used in most of examples was not resolvable and accessible that was because of existence of old version in global grails lib through some dependency to garils-doc and itext (The dependencies can be checked by grails dependency-report command). So first solution was to exclude the bouncycastle lib in BuildConfig.groovy of my plugin by something like the following code:

dependencies {
 compile("com.lowagie:itext:2.0.8") {
  excludes "bouncycastle:bcprov-jdk14:138", "org.bouncycastle:bcprov-jdk14:1.38"
 }
}

It was OK for compiling source code in plugin project but same error of not founding some classes repeated on application project that use the plugin. So I added same to build config of application and it resolved. So now I can encrypt and decrypt strings by RSA keys in grails side.

I added syntax highlighter to blog template for this post.

No comments: