refactored worker code... all asym and sym batch encryption is done in a worker

This commit is contained in:
Tankred Hase 2013-05-15 13:11:08 +02:00
parent fcf64569b2
commit 98a4b8cfec
7 changed files with 141 additions and 60 deletions

View File

@ -13,18 +13,18 @@
*/ */
self.onmessage = function(e) { self.onmessage = function(e) {
var args = e.data, var i = e.data,
output = null, output = null,
aes = new app.crypto.AesCBC(forge), aes = new app.crypto.AesCBC(forge),
util = new app.crypto.Util(null, null); util = new app.crypto.Util(null, null);
if (args.type === 'encrypt' && args.list) { if (i.type === 'encrypt' && i.list) {
// start encryption // start encryption
output = util.encryptList(aes, args.list); output = util.encryptList(aes, i.list);
} else if (args.type === 'decrypt' && args.list) { } else if (i.type === 'decrypt' && i.list) {
// start decryption // start decryption
output = util.decryptList(aes, args.list); output = util.decryptList(aes, i.list);
} else { } else {
throw 'Not all arguments for web worker crypto are defined!'; throw 'Not all arguments for web worker crypto are defined!';

View File

@ -12,17 +12,17 @@
*/ */
self.onmessage = function(e) { self.onmessage = function(e) {
var args = e.data, var i = e.data,
output = null, output = null,
aes = new app.crypto.AesCBC(forge); aes = new app.crypto.AesCBC(forge);
if (args.type === 'encrypt' && args.plaintext && args.key && args.iv) { if (i.type === 'encrypt' && i.plaintext && i.key && i.iv) {
// start encryption // start encryption
output = aes.encrypt(args.plaintext, args.key, args.iv); output = aes.encrypt(i.plaintext, i.key, i.iv);
} else if (args.type === 'decrypt' && args.ciphertext && args.key && args.iv) { } else if (i.type === 'decrypt' && i.ciphertext && i.key && i.iv) {
// start decryption // start decryption
output = aes.decrypt(args.ciphertext, args.key, args.iv); output = aes.decrypt(i.ciphertext, i.key, i.iv);
} else { } else {
throw 'Not all arguments for web worker crypto are defined!'; throw 'Not all arguments for web worker crypto are defined!';

View File

@ -0,0 +1,41 @@
(function() {
'use strict';
// import web worker dependencies
importScripts('../../lib/forge/forge.rsa.bundle.js');
importScripts('../app-config.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
* variable namespace similar to the 'window' object in the main thread
*/
self.onmessage = function(e) {
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.init(i.pubkeyPem, i.privkeyPem);
if (i.type === 'encrypt' && i.list) {
// start encryption
output = util.encryptListForUser(aes, rsa, i.list);
} else if (i.type === 'decrypt' && i.list) {
// start decryption
output = util.decryptListForUser(aes, rsa, i.list);
} else {
throw 'Not all arguments for web worker crypto are defined!';
}
// pass output back to main thread
self.postMessage(output);
};
}());

View File

@ -224,55 +224,47 @@ app.crypto.Crypto = function(window, util) {
envelopes.push(envelope); envelopes.push(envelope);
}); });
// encrypt list if (window.Worker) {
this.aesEncryptList(envelopes, function(encryptedList) {
// encrypt keys for user var keypair = rsa.exportKeys();
encryptedList.forEach(function(i) {
// process new values var worker = new Worker(app.config.workerPath + '/crypto/crypto-batch-worker.js');
i.itemIV = i.iv; worker.onmessage = function(e) {
i.encryptedKey = rsa.encrypt(i.key); callback(null, e.data);
i.keyIV = rsa.sign([i.itemIV, i.encryptedKey, i.ciphertext]); };
// delete old ones worker.postMessage({
delete i.iv; type: 'encrypt',
delete i.key; list: envelopes,
pubkeyPem: keypair.pubkeyPem,
privkeyPem: keypair.privkeyPem
}); });
} else {
var encryptedList = util.encryptListForUser(aes, rsa, envelopes);
callback(null, encryptedList); callback(null, encryptedList);
}); }
}; };
this.decryptListForUser = function(encryptedList, recipientPubkey, callback) { this.decryptListForUser = function(list, recipientPubkey, callback) {
var list = [], if (window.Worker) {
self = this;
// decrypt keys for user var keypair = rsa.exportKeys();
encryptedList.forEach(function(i) {
// verify signature
if (!rsa.verify([i.itemIV, i.encryptedKey, i.ciphertext], i.keyIV)) {
callback({
errMsg: 'Verifying RSA signature failed!'
});
return;
}
// 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 worker = new Worker(app.config.workerPath + '/crypto/crypto-batch-worker.js');
this.aesDecryptList(encryptedList, function(decryptedList) { worker.onmessage = function(e) {
// add plaintext to list callback(null, e.data);
decryptedList.forEach(function(i) { };
list.push(i.plaintext); worker.postMessage({
type: 'decrypt',
list: list,
pubkeyPem: keypair.pubkeyPem,
privkeyPem: keypair.privkeyPem
}); });
callback(null, list); } else {
}); var decryptedList = util.decryptListForUser(aes, rsa, list);
callback(null, decryptedList);
}
}; };
}; };

View File

@ -10,24 +10,24 @@
*/ */
self.onmessage = function(e) { self.onmessage = function(e) {
var args = e.data, var i = e.data,
output = null; output = null;
if (args.type === 'keygen') { if (i.type === 'keygen') {
// generate keypair // generate keypair
if (args.seed) { if (i.seed) {
output = nacl.crypto_box_keypair_from_seed(args.seed); output = nacl.crypto_box_keypair_from_seed(i.seed);
} else { } else {
output = nacl.crypto_box_keypair(); output = nacl.crypto_box_keypair();
} }
} else if (args.type === 'encrypt' && args.plaintext && args.nonce && args.recipientPk && args.senderSk) { } else if (i.type === 'encrypt' && i.plaintext && i.nonce && i.recipientPk && i.senderSk) {
// start encryption // start encryption
output = nacl.crypto_box(args.plaintext, args.nonce, args.recipientPk, args.senderSk); output = nacl.crypto_box(i.plaintext, i.nonce, i.recipientPk, i.senderSk);
} else if (args.type === 'decrypt' && args.ciphertext && args.nonce && args.senderPk && args.recipienSk) { } else if (i.type === 'decrypt' && i.ciphertext && i.nonce && i.senderPk && i.recipienSk) {
// start decryption // start decryption
output = nacl.crypto_box_open(args.ciphertext, args.nonce, args.senderPk, args.recipienSk); output = nacl.crypto_box_open(i.ciphertext, i.nonce, i.senderPk, i.recipienSk);
} else { } else {
throw 'Not all arguments for web worker crypto are defined!'; throw 'Not all arguments for web worker crypto are defined!';

View File

@ -12,13 +12,13 @@
*/ */
self.onmessage = function(e) { self.onmessage = function(e) {
var args = e.data, var i = e.data,
key = null; key = null;
if (e.data.password && e.data.keySize) { if (i.password && i.keySize) {
// start deriving key // start deriving key
var pbkdf2 = new app.crypto.PBKDF2(); var pbkdf2 = new app.crypto.PBKDF2();
key = pbkdf2.getKey(e.data.password, e.data.keySize); key = pbkdf2.getKey(i.password, i.keySize);
} else { } else {
throw 'Not all arguments for web worker crypto are defined!'; throw 'Not all arguments for web worker crypto are defined!';

View File

@ -59,6 +59,24 @@ var Util = function(window, uuid, crypt) {
return outList; 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 * Decrypt a list of items
* @param aes [Object] The object implementing the aes mode * @param aes [Object] The object implementing the aes mode
@ -80,6 +98,36 @@ var Util = function(window, uuid, crypt) {
return outList; 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" * Parse a date string with the following format "1900-01-31 18:17:53"
*/ */