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) {
var args = e.data,
var i = e.data,
output = null,
aes = new app.crypto.AesCBC(forge),
util = new app.crypto.Util(null, null);
if (args.type === 'encrypt' && args.list) {
if (i.type === 'encrypt' && i.list) {
// 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
output = util.decryptList(aes, args.list);
output = util.decryptList(aes, i.list);
} else {
throw 'Not all arguments for web worker crypto are defined!';

View File

@ -12,17 +12,17 @@
*/
self.onmessage = function(e) {
var args = e.data,
var i = e.data,
output = null,
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
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
output = aes.decrypt(args.ciphertext, args.key, args.iv);
output = aes.decrypt(i.ciphertext, i.key, i.iv);
} else {
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);
});
// encrypt list
this.aesEncryptList(envelopes, function(encryptedList) {
if (window.Worker) {
// 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;
var keypair = rsa.exportKeys();
var worker = new Worker(app.config.workerPath + '/crypto/crypto-batch-worker.js');
worker.onmessage = function(e) {
callback(null, e.data);
};
worker.postMessage({
type: 'encrypt',
list: envelopes,
pubkeyPem: keypair.pubkeyPem,
privkeyPem: keypair.privkeyPem
});
} else {
var encryptedList = util.encryptListForUser(aes, rsa, envelopes);
callback(null, encryptedList);
});
}
};
this.decryptListForUser = function(encryptedList, recipientPubkey, callback) {
var list = [],
self = this;
this.decryptListForUser = function(list, recipientPubkey, callback) {
if (window.Worker) {
// decrypt keys for user
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;
});
var keypair = rsa.exportKeys();
// decrypt list
this.aesDecryptList(encryptedList, function(decryptedList) {
// add plaintext to list
decryptedList.forEach(function(i) {
list.push(i.plaintext);
var worker = new Worker(app.config.workerPath + '/crypto/crypto-batch-worker.js');
worker.onmessage = function(e) {
callback(null, e.data);
};
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) {
var args = e.data,
var i = e.data,
output = null;
if (args.type === 'keygen') {
if (i.type === 'keygen') {
// generate keypair
if (args.seed) {
output = nacl.crypto_box_keypair_from_seed(args.seed);
if (i.seed) {
output = nacl.crypto_box_keypair_from_seed(i.seed);
} else {
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
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
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 {
throw 'Not all arguments for web worker crypto are defined!';

View File

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

View File

@ -59,6 +59,24 @@ var Util = function(window, uuid, crypt) {
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
@ -80,6 +98,36 @@ var Util = function(window, uuid, crypt) {
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"
*/