CryptoJS libraries for Google Apps Script

CryptoJS is pretty much the gold standard for JavaScript cryptography. Working with Oauth2 you don't have to worry about all that, except when you are dealing with service accounts. I'll get to that in a another section, but first let's look at a CryptoJS library for Google Apps Script.

One thing I discovered is that GAS is pretty slow at some things. Heavy compute tasks like cryptography is one of them. I had previously used sjcl encryption for  parse.com - noSQL database for GAS but gave up on it because it was just too slow. CyptoJS is better and fine for one off encryptions. However it's much slower than running in your browser. More of that later. 

The library

cCryptoGS is available here 

MSJnPeIon6nzdLewGV60xWqi_d-phDA33

Usage

Many hashing functions are already included in GAS Utilities service, so all I really need is the Cipher algorithms for encrypting messages, so I've made a simple wrapper. Here's an example

 var cipher = new cCryptoGS.Cipher('this is my passphrase', 'aes');
 var encryptedMessage = cipher.encrypt ('this is my message to be encrypted');
 var decryptedMessage = cipher.decrypt (encryptedMessage);

 Logger.log (encryptedMessage);
   U2FsdGVkX1/IPjBXkX/zgfYipqso1RcgWwgvXre9yWXMt+hzsOk5FmLeI5zEF1nHuXGbuPqrafyTao1BCO4n4w==

 Logger.log (decryptedMessage);
   this is my message to be encrypted

Algorithms

For now I've included these algorithms

var ALGOS = ['AES','DES','Rabbit','TripleDES'];

If you have need of any others, let me know on G+

CryptoJS direct

If you need to call some of the cipher functions in CryptoJS directly, you can do that too. Here's the above example without the wrapper

 var encryptedMessage = cCryptoGS.CryptoJS.AES.encrypt ('this is my message to be encrypted', 'this is my passphrase').toString();
 var decryptedMessage = cCryptoGS.CryptoJS.AES.decrypt (encryptedMessage, 'this is my passphrase').toString(CryptoJS.enc.Utf8);

Performance

Of the implemented algorithms, Rabbit is the fastest - about half a second for an encrypt/decrypt pair. Here's a test running 100 encrypts/decrypts

  var looper = 100;
  var pass = "some passphrase";
  var message = "some kind of message to be encrypted";

  // simplified
  ['AES','DES','Rabbit','TripleDES'].forEach (function(d) {
    var cipher = new cCryptoGS.Cipher(pass, d);
    var start = new Date().getTime();    
    for (var i=0; i < looper ; i++ ) { 
      var enc = cipher.encrypt (message);
      var dec = cipher.decrypt (enc);
      if (dec !== message) {
        throw 'mismatch' + ' . ' + dec + ' . ' + message;
      }
    }
    var end = new Date().getTime();
    Logger.log( d+' ' + looper + ' iterations took ' + (end - start));
  });

But when you compare that with the same thing running on a regular javascript client app, you get this amazing difference, so we again learn that any form of big compute on GAS infrastructure is not a good thing.


So what's going on? At first I thought there might some kind of caja thing going on, so I ran it again from htmlService - executing on the client, but caja-fied. Sure it takes a bit longer than purely on the client - but not that much longer.



Here's all 3 tests




Need to think some more....
For help and more information join our community,  follow the blog,  follow me on twitter, or follow me on g+

You want to learn Google Apps Script?

Learning Apps Script, (and transitioning from VBA) are covered comprehensively in my my book, Going Gas - from VBA to Apps script, All formats are available from O'ReillyAmazon and all good bookshops. You can also read a preview on O'Reilly

If you prefer Video style learning I also have two courses available. also published by O'Reilly.
Google Apps Script for Developers and Google Apps Script for Beginners.


Comments