moved nacl key derivation to web worker

This commit is contained in:
Tankred Hase 2013-04-29 15:10:27 +02:00
parent 2259ac753e
commit 6177b40f1b
5 changed files with 86 additions and 38 deletions

View File

@ -81,12 +81,13 @@ app.crypto.Crypto = function(window, util) {
/**
* Derive an asymmetric keypait from the user's secret
*/
this.deriveKeyPair = function(naclCrypto) {
var keys = naclCrypto.generateKeypair(symmetricUserKey);
if (keyId) {
keys.id = keyId;
}
return keys;
this.deriveKeyPair = function(naclCrypto, callback) {
naclCrypto.generateKeypair(symmetricUserKey, function(keys) {
if (keyId) {
keys.id = keyId;
}
callback(keys);
});
};
//

View File

@ -8,21 +8,49 @@ var NaclCrypto = function(nacl, util) {
* Generates a baes64 encoded keypair for use with NaCl
* @param seed [String] A base64 encoded (pseudo) random seed e.g. PBKDF2
*/
this.generateKeypair = function(seed) {
var keys;
this.generateKeypair = function(seed, callback) {
var keys, seedBuf;
if (seed) {
var seedBuf = nacl.encode_latin1(util.base642Str(seed));
keys = nacl.crypto_box_keypair_from_seed(seedBuf);
} else {
keys = nacl.crypto_box_keypair();
}
// do key deterministic derivation from pseudo random seed
seedBuf = nacl.encode_latin1(util.base642Str(seed));
return {
id: util.UUID(),
boxPk: util.str2Base64(nacl.decode_latin1(keys.boxPk)),
boxSk: util.str2Base64(nacl.decode_latin1(keys.boxSk))
};
if (Worker) {
var worker = new Worker(app.config.workerPath + '/crypto/nacl-worker.js');
worker.onmessage = function(e) {
callback({
id: util.UUID(),
boxPk: util.str2Base64(nacl.decode_latin1(e.data.boxPk)),
boxSk: util.str2Base64(nacl.decode_latin1(e.data.boxSk))
});
};
worker.postMessage({
type: 'keygen',
seed: seedBuf
});
} else {
// no web worker support
keys = nacl.crypto_box_keypair_from_seed(seedBuf);
callback({
id: util.UUID(),
boxPk: util.str2Base64(nacl.decode_latin1(keys.boxPk)),
boxSk: util.str2Base64(nacl.decode_latin1(keys.boxSk))
});
}
} else {
// generate keypiar from random values
keys = nacl.crypto_box_keypair();
callback({
id: util.UUID(),
boxPk: util.str2Base64(nacl.decode_latin1(keys.boxPk)),
boxSk: util.str2Base64(nacl.decode_latin1(keys.boxSk))
});
}
};
/**

View File

@ -13,7 +13,15 @@
var args = e.data,
output = null;
if (args.type === 'encrypt' && args.plaintext && args.nonce && args.recipientPk && args.senderSk) {
if (args.type === 'keygen') {
// generate keypair
if (args.seed) {
output = nacl.crypto_box_keypair_from_seed(args.seed);
} else {
output = nacl.crypto_box_keypair();
}
} else if (args.type === 'encrypt' && args.plaintext && args.nonce && args.recipientPk && args.senderSk) {
// start encryption
output = nacl.crypto_box(args.plaintext, args.nonce, args.recipientPk, args.senderSk);

View File

@ -36,15 +36,18 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, naclCrypto,
function initNaclCrypto() {
// derive keypair from user's secret key
keypair = crypto.deriveKeyPair(naclCrypto);
//publish public key to cloud service
var pubkey = new app.model.PublicKey({
_id: keypair.id,
userId: account.get('emailAddress'),
publicKey: keypair.boxPk
});
cloudstorage.putPublicKey(pubkey.toJSON(), function(err) {
callback(err);
crypto.deriveKeyPair(naclCrypto, function(generated) {
keypair = generated;
//publish public key to cloud service
var pubkey = new app.model.PublicKey({
_id: keypair.id,
userId: account.get('emailAddress'),
publicKey: keypair.boxPk
});
cloudstorage.putPublicKey(pubkey.toJSON(), function(err) {
callback(err);
});
});
}
};

View File

@ -14,22 +14,30 @@ test("Init", 1, function() {
nacl_test.crypto = new app.crypto.NaclCrypto(nacl, nacl_test.util);
});
test("Generate Keypair from seed", 1, function() {
asyncTest("Generate Keypair from seed", 1, function() {
// generate keypair from seed
var seed = nacl_test.util.random(128);
var keys = nacl_test.crypto.generateKeypair(seed);
ok(keys.boxSk && keys.boxPk && keys.id, "Keypair: " + JSON.stringify(keys));
nacl_test.crypto.generateKeypair(seed, function(keys) {
ok(keys.boxSk && keys.boxPk && keys.id, "Keypair: " + JSON.stringify(keys));
start();
});
});
test("Generate Keypair", 2, function() {
asyncTest("Generate Keypair", 2, function() {
// generate keypair
var senderKeypair = nacl_test.crypto.generateKeypair();
ok(senderKeypair.boxSk && senderKeypair.boxPk, "Sender keypair: " + JSON.stringify(senderKeypair));
var recipientKeypair = nacl_test.crypto.generateKeypair();
ok(recipientKeypair.boxSk && recipientKeypair.boxPk, "Receiver keypair: " + JSON.stringify(recipientKeypair));
nacl_test.crypto.generateKeypair(null, function(senderKeypair) {
ok(senderKeypair.boxSk && senderKeypair.boxPk, "Sender keypair: " + JSON.stringify(senderKeypair));
nacl_test.senderKeypair = senderKeypair;
nacl_test.recipientKeypair = recipientKeypair;
nacl_test.crypto.generateKeypair(null, function(recipientKeypair) {
ok(recipientKeypair.boxSk && recipientKeypair.boxPk, "Receiver keypair: " + JSON.stringify(recipientKeypair));
nacl_test.senderKeypair = senderKeypair;
nacl_test.recipientKeypair = recipientKeypair;
start();
});
});
});
test("Asymmetric En/Decrypt (Synchronous)", 3, function() {