From 6f2be99672c1aeed4601ed9d7246600f4ae4ecb2 Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Wed, 15 May 2013 13:36:59 +0200 Subject: [PATCH] moved crypto batch code from util to own js file --- src/js/crypto/aes-batch-worker.js | 8 +- src/js/crypto/crypto-batch-worker.js | 11 +-- src/js/crypto/crypto-batch.js | 116 +++++++++++++++++++++++++++ src/js/crypto/crypto.js | 12 ++- src/js/crypto/util.js | 90 --------------------- test/unit/index.html | 1 + 6 files changed, 135 insertions(+), 103 deletions(-) create mode 100644 src/js/crypto/crypto-batch.js diff --git a/src/js/crypto/aes-batch-worker.js b/src/js/crypto/aes-batch-worker.js index d24e8a8..e6f21cb 100644 --- a/src/js/crypto/aes-batch-worker.js +++ b/src/js/crypto/aes-batch-worker.js @@ -4,8 +4,8 @@ // import web worker dependencies importScripts('../../lib/forge/forge.rsa.bundle.js'); importScripts('../app-config.js'); + importScripts('./crypto-batch.js'); importScripts('./aes-cbc.js'); - importScripts('./util.js'); /** * In the web worker thread context, 'this' and 'self' can be used as a global @@ -16,15 +16,15 @@ var i = e.data, output = null, aes = new app.crypto.AesCBC(forge), - util = new app.crypto.Util(null, null); + batch = new app.crypto.CryptoBatch(aes); if (i.type === 'encrypt' && i.list) { // start encryption - output = util.encryptList(aes, i.list); + output = batch.encryptList(i.list); } else if (i.type === 'decrypt' && i.list) { // start decryption - output = util.decryptList(aes, i.list); + output = batch.decryptList(i.list); } else { throw 'Not all arguments for web worker crypto are defined!'; diff --git a/src/js/crypto/crypto-batch-worker.js b/src/js/crypto/crypto-batch-worker.js index 7198d5f..c933f68 100644 --- a/src/js/crypto/crypto-batch-worker.js +++ b/src/js/crypto/crypto-batch-worker.js @@ -4,9 +4,9 @@ // import web worker dependencies importScripts('../../lib/forge/forge.rsa.bundle.js'); importScripts('../app-config.js'); + importScripts('./crypto-batch.js'); importScripts('./aes-cbc.js'); importScripts('./rsa.js'); - importScripts('./util.js'); /** * In the web worker thread context, 'this' and 'self' can be used as a global @@ -16,19 +16,20 @@ var i = e.data, output = null, - util = new app.crypto.Util(null, null), aes = new app.crypto.AesCBC(forge), - rsa = new app.crypto.RSA(forge, util); + rsa = new app.crypto.RSA(forge), + batch = new app.crypto.CryptoBatch(aes, rsa); + // pass RSA keys to module rsa.init(i.pubkeyPem, i.privkeyPem); if (i.type === 'encrypt' && i.list) { // start encryption - output = util.encryptListForUser(aes, rsa, i.list); + output = batch.encryptListForUser(i.list); } else if (i.type === 'decrypt' && i.list) { // start decryption - output = util.decryptListForUser(aes, rsa, i.list); + output = batch.decryptListForUser(i.list); } else { throw 'Not all arguments for web worker crypto are defined!'; diff --git a/src/js/crypto/crypto-batch.js b/src/js/crypto/crypto-batch.js new file mode 100644 index 0000000..5a823a6 --- /dev/null +++ b/src/js/crypto/crypto-batch.js @@ -0,0 +1,116 @@ +/** + * Crypto batch library for processing large sets of data + */ +var CryptoBatch = function(aes, rsa) { + 'use strict'; + + // + // Encryption + // + + /** + * Encrypt a list of items using AES + * @list list [Array] The list of items to encrypt + */ + this.encryptList = function(list) { + var outList = []; + + list.forEach(function(i) { + // stringify to JSON before encryption + outList.push({ + id: i.id, + ciphertext: aes.encrypt(JSON.stringify(i.plaintext), i.key, i.iv), + key: i.key, + iv: i.iv + }); + }); + + return outList; + }; + + /** + * Encrypt a list of items using AES and RSA + * @list list [Array] The list of items to encrypt + */ + this.encryptListForUser = function(list) { + // encrypt list + var encryptedList = this.encryptList(list); + + // encrypt keys for user + encryptedList.forEach(function(i) { + // process new values + i.itemIV = i.iv; + i.encryptedKey = rsa.encrypt(i.key); + i.keyIV = rsa.sign([i.itemIV, i.encryptedKey, i.ciphertext]); + // delete old ones + delete i.iv; + delete i.key; + }); + + return encryptedList; + }; + + // + // Decryption + // + + /** + * Decrypt a list of items using AES + * @list list [Array] The list of items to decrypt + */ + this.decryptList = function(list) { + var outList = []; + + list.forEach(function(i) { + // decrypt JSON and parse to object literal + outList.push({ + id: i.id, + plaintext: JSON.parse(aes.decrypt(i.ciphertext, i.key, i.iv)), + key: i.key, + iv: i.iv + }); + }); + + return outList; + }; + + /** + * Decrypt a list of items using AES and RSA + * @list list [Array] The list of items to decrypt + */ + this.decryptListForUser = function(encryptedList) { + var list = [], + self = this; + + // decrypt keys for user + encryptedList.forEach(function(i) { + // verify signature + if (!rsa.verify([i.itemIV, i.encryptedKey, i.ciphertext], i.keyIV)) { + throw new Error('Verifying RSA signature failed!'); + } + // precoess new values + i.iv = i.itemIV; + i.key = rsa.decrypt(i.encryptedKey); + // delete old values + delete i.keyIV; + delete i.itemIV; + delete i.encryptedKey; + }); + + // decrypt list + var decryptedList = this.decryptList(encryptedList); + + // add plaintext to list + decryptedList.forEach(function(i) { + list.push(i.plaintext); + }); + + return list; + }; +}; + +if (typeof module !== 'undefined' && module.exports) { + module.exports = CryptoBatch; +} else { + app.crypto.CryptoBatch = CryptoBatch; +} \ No newline at end of file diff --git a/src/js/crypto/crypto.js b/src/js/crypto/crypto.js index e463a5a..c141e25 100644 --- a/src/js/crypto/crypto.js +++ b/src/js/crypto/crypto.js @@ -182,7 +182,8 @@ app.crypto.Crypto = function(window, util) { }); } else { - var encryptedList = util.encryptList(aes, list); + var batch = new app.crypto.CryptoBatch(aes); + var encryptedList = batch.encryptList(list); callback(encryptedList); } }; @@ -200,7 +201,8 @@ app.crypto.Crypto = function(window, util) { }); } else { - var decryptedList = util.decryptList(aes, list); + var batch = new app.crypto.CryptoBatch(aes); + var decryptedList = batch.decryptList(list); callback(decryptedList); } }; @@ -240,7 +242,8 @@ app.crypto.Crypto = function(window, util) { }); } else { - var encryptedList = util.encryptListForUser(aes, rsa, envelopes); + var batch = new app.crypto.CryptoBatch(aes, rsa); + var encryptedList = batch.encryptListForUser(envelopes); callback(null, encryptedList); } }; @@ -262,7 +265,8 @@ app.crypto.Crypto = function(window, util) { }); } else { - var decryptedList = util.decryptListForUser(aes, rsa, list); + var batch = new app.crypto.CryptoBatch(aes, rsa); + var decryptedList = batch.decryptListForUser(list); callback(null, decryptedList); } }; diff --git a/src/js/crypto/util.js b/src/js/crypto/util.js index e7a0025..13069f1 100644 --- a/src/js/crypto/util.js +++ b/src/js/crypto/util.js @@ -38,96 +38,6 @@ var Util = function(window, uuid, crypt) { return keyBase64; }; - /** - * Encrypt a list of items - * @param aes [Object] The object implementing the aes mode - * @list list [Array] The list of items to encrypt - */ - this.encryptList = function(aes, list) { - var outList = []; - - list.forEach(function(i) { - // stringify to JSON before encryption - outList.push({ - id: i.id, - ciphertext: aes.encrypt(JSON.stringify(i.plaintext), i.key, i.iv), - key: i.key, - iv: i.iv - }); - }); - - return outList; - }; - - this.encryptListForUser = function(aes, rsa, list) { - // encrypt list - var encryptedList = this.encryptList(aes, list); - - // encrypt keys for user - encryptedList.forEach(function(i) { - // process new values - i.itemIV = i.iv; - i.encryptedKey = rsa.encrypt(i.key); - i.keyIV = rsa.sign([i.itemIV, i.encryptedKey, i.ciphertext]); - // delete old ones - delete i.iv; - delete i.key; - }); - - return encryptedList; - }; - - /** - * Decrypt a list of items - * @param aes [Object] The object implementing the aes mode - * @list list [Array] The list of items to decrypt - */ - this.decryptList = function(aes, list) { - var outList = []; - - list.forEach(function(i) { - // decrypt JSON and parse to object literal - outList.push({ - id: i.id, - plaintext: JSON.parse(aes.decrypt(i.ciphertext, i.key, i.iv)), - key: i.key, - iv: i.iv - }); - }); - - return outList; - }; - - this.decryptListForUser = function(aes, rsa, encryptedList) { - var list = [], - self = this; - - // decrypt keys for user - encryptedList.forEach(function(i) { - // verify signature - if (!rsa.verify([i.itemIV, i.encryptedKey, i.ciphertext], i.keyIV)) { - throw new Error('Verifying RSA signature failed!'); - } - // precoess new values - i.iv = i.itemIV; - i.key = rsa.decrypt(i.encryptedKey); - // delete old values - delete i.keyIV; - delete i.itemIV; - delete i.encryptedKey; - }); - - // decrypt list - var decryptedList = this.decryptList(aes, encryptedList); - - // add plaintext to list - decryptedList.forEach(function(i) { - list.push(i.plaintext); - }); - - return list; - }; - /** * Parse a date string with the following format "1900-01-31 18:17:53" */ diff --git a/test/unit/index.html b/test/unit/index.html index 01f0e6b..b57cd42 100644 --- a/test/unit/index.html +++ b/test/unit/index.html @@ -44,6 +44,7 @@ +