webworker support for js-nacl works

This commit is contained in:
Tankred Hase 2013-04-10 17:09:39 +02:00
parent 6841bd538c
commit edf78bc1af
4 changed files with 10791 additions and 449 deletions

View File

@ -24,30 +24,37 @@ var NaclCrypto = function(nacl, util) {
};
};
/**
* Generates a random nonce and returns it base64 encoded
*/
this.generateNonce = function() {
// generate nonce
var nonce = nacl.crypto_secretbox_random_nonce();
var nonceBase64 = util.str2Base64(nacl.decode_latin1(nonce));
return nonceBase64;
};
/**
* Asymmetrically encrypt a String
* @param plaintext [String] The input string in UTF8
* @param nonce [String] The base64 encoded nonce
* @param recipientBoxPk [String] The receiver's base64 encoded public key
* @param senderBoxSk [String] The sender's base64 encoded private key
* @return [Object] The base64 encoded ciphertext and nonce
*/
this.asymmetricEncrypt = function(plaintext, recipientBoxPk, senderBoxSk) {
this.asymmetricEncrypt = function(plaintext, nonce, recipientBoxPk, senderBoxSk) {
// convert to Uint8Array
var ptBuf = nacl.encode_utf8(plaintext);
var recipientBoxPkBuf = nacl.encode_latin1(util.base642Str(recipientBoxPk));
var senderBoxSkBuf = nacl.encode_latin1(util.base642Str(senderBoxSk));
// generate nonce
var nonce = nacl.crypto_secretbox_random_nonce();
var nonceBuf = nacl.encode_latin1(util.base642Str(nonce));
// encrypt
var ct = nacl.crypto_box(ptBuf, nonce, recipientBoxPkBuf, senderBoxSkBuf);
var ct = nacl.crypto_box(ptBuf, nonceBuf, recipientBoxPkBuf, senderBoxSkBuf);
// encode to base64
var ctBase64 = util.str2Base64(nacl.decode_latin1(ct));
var nonceBase64 = util.str2Base64(nacl.decode_latin1(nonce));
return {
ct: ctBase64,
nonce: nonceBase64
};
return ctBase64;
};
/**
@ -75,25 +82,21 @@ var NaclCrypto = function(nacl, util) {
/**
* Symmetrically encrypt a String
* @param plaintext [String] The input string in UTF8
* @param nonce [String] The base64 encoded nonce
* @param secretKey [String] The receiver's base64 encoded public key
* @return [Object] The base64 encoded ciphertext and nonce
*/
this.symmetricEncrypt = function(plaintext, secretKey) {
this.symmetricEncrypt = function(plaintext, nonce, secretKey) {
// convert to Uint8Array
var ptBuf = nacl.encode_utf8(plaintext);
var secretKeyBuf = nacl.encode_latin1(util.base642Str(secretKey));
// generate nonce
var nonce = nacl.crypto_secretbox_random_nonce();
var nonceBuf = nacl.encode_latin1(util.base642Str(nonce));
// encrypt
var ct = nacl.crypto_secretbox(ptBuf, nonce, secretKeyBuf);
var ct = nacl.crypto_secretbox(ptBuf, nonceBuf, secretKeyBuf);
// encode to base64
var ctBase64 = util.str2Base64(nacl.decode_latin1(ct));
var nonceBase64 = util.str2Base64(nacl.decode_latin1(nonce));
return {
ct: ctBase64,
nonce: nonceBase64
};
return ctBase64;
};
/**

View File

@ -0,0 +1,37 @@
(function() {
'use strict';
// import web worker dependencies
importScripts('../../lib/nacl.js');
importScripts('../app-config.js');
importScripts('./util.js');
importScripts('./nacl-crypto.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 args = e.data,
output = null,
util = new app.crypto.Util(),
crypto = new app.crypto.NaclCrypto(nacl, util);
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);
} else if (args.type === 'decrypt' && args.ciphertext && args.nonce && args.senderPk && args.recipienSk) {
// start decryption
output = nacl.crypto_box_open(args.ciphertext, args.nonce, args.senderPk, args.recipienSk);
} else {
throw 'Not all arguments for web worker crypto are defined!';
}
// pass output back to main thread
self.postMessage(output);
};
}());

File diff suppressed because one or more lines are too long

View File

@ -31,27 +31,77 @@ test("Generate Keypair", 2, function() {
nacl_test.recipientKeypair = recipientKeypair;
});
test("Asymmetric En/Decrypt", 2, function() {
test("Asymmetric En/Decrypt", 3, function() {
var plaintext = nacl_test.test_message;
var nonce = nacl_test.crypto.generateNonce();
ok(nonce, 'Nonce: ' + nonce);
// encrypt
var ct = nacl_test.crypto.asymmetricEncrypt(plaintext, nacl_test.recipientKeypair.boxPk, nacl_test.senderKeypair.boxSk);
ok(ct.ct && ct.nonce, 'Ciphertext length: ' + ct.ct.length);
var ct = nacl_test.crypto.asymmetricEncrypt(plaintext, nonce, nacl_test.recipientKeypair.boxPk, nacl_test.senderKeypair.boxSk);
ok(ct, 'Ciphertext length: ' + ct.length);
// decrypt
var decrypted = nacl_test.crypto.asymmetricDecrypt(ct.ct, ct.nonce, nacl_test.senderKeypair.boxPk, nacl_test.recipientKeypair.boxSk);
var decrypted = nacl_test.crypto.asymmetricDecrypt(ct, nonce, nacl_test.senderKeypair.boxPk, nacl_test.recipientKeypair.boxSk);
equal(decrypted, plaintext, 'Decryption correct: ' + decrypted);
});
test("Symmetric En/Decrypt", 2, function() {
test("Symmetric En/Decrypt", 3, function() {
var plaintext = nacl_test.test_message;
var nonce = nacl_test.crypto.generateNonce();
ok(nonce, 'Nonce: ' + nonce);
// encrypt
var ct = nacl_test.crypto.symmetricEncrypt(plaintext, nacl_test.senderKeypair.boxSk);
ok(ct.ct && ct.nonce, 'Ciphertext length: ' + ct.ct.length);
var ct = nacl_test.crypto.symmetricEncrypt(plaintext, nonce, nacl_test.senderKeypair.boxSk);
ok(ct, 'Ciphertext length: ' + ct.length);
// decrypt
var decrypted = nacl_test.crypto.symmetricDecrypt(ct.ct, ct.nonce, nacl_test.senderKeypair.boxSk);
var decrypted = nacl_test.crypto.symmetricDecrypt(ct, nonce, nacl_test.senderKeypair.boxSk);
equal(decrypted, plaintext, 'Decryption correct: ' + decrypted);
});
asyncTest("Asymmetric En/Decrypt (WebWorker)", 3, function() {
var plaintext = nacl.encode_utf8(nacl_test.test_message),
nonce = nacl.crypto_secretbox_random_nonce(),
utl = nacl_test.util,
recipientPk = utl.binStr2Uint8Arr(utl.base642Str(nacl_test.recipientKeypair.boxPk)),
senderSk = utl.binStr2Uint8Arr(utl.base642Str(nacl_test.senderKeypair.boxSk)),
recipienSk = utl.binStr2Uint8Arr(utl.base642Str(nacl_test.recipientKeypair.boxSk)),
senderPk = utl.binStr2Uint8Arr(utl.base642Str(nacl_test.senderKeypair.boxPk));
// encrypt
function encrypt(pt) {
var encryptWorker = new Worker(app.config.workerPath + '/crypto/nacl-worker.js');
encryptWorker.onmessage = function(e) {
ok(e.data, 'Encryption');
decrypt(e.data);
};
encryptWorker.postMessage({
type: 'encrypt',
plaintext: pt,
nonce: nonce,
recipientPk: recipientPk,
senderSk: senderSk
});
}
// decrypt
function decrypt(ct) {
var decryptWorker = new Worker(app.config.workerPath + '/crypto/nacl-worker.js');
decryptWorker.onmessage = function(e) {
ok(e.data, 'Decryption');
deepEqual(e.data, plaintext, 'Decrypted = Plaintext');
start();
};
decryptWorker.postMessage({
type: 'decrypt',
ciphertext: ct,
nonce: nonce,
senderPk: senderPk,
recipienSk: recipienSk
});
}
encrypt(plaintext);
});