2013-04-04 08:28:07 -04:00
|
|
|
/**
|
|
|
|
* A Wrapper for NaCl's asymmetric/symmetric crypto
|
|
|
|
*/
|
2013-04-05 12:38:14 -04:00
|
|
|
var NaclCrypto = function(nacl, util) {
|
2013-04-04 08:28:07 -04:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
/**
|
2013-04-04 15:36:29 -04:00
|
|
|
* Generates a baes64 encoded keypair for use with NaCl
|
2013-04-05 11:56:47 -04:00
|
|
|
* @param seed [String] A base64 encoded (pseudo) random seed e.g. PBKDF2
|
2013-04-04 15:36:29 -04:00
|
|
|
*/
|
2013-04-29 09:10:27 -04:00
|
|
|
this.generateKeypair = function(seed, callback) {
|
|
|
|
var keys, seedBuf;
|
2013-04-05 11:56:47 -04:00
|
|
|
|
2013-04-04 15:36:29 -04:00
|
|
|
if (seed) {
|
2013-04-29 09:10:27 -04:00
|
|
|
// do key deterministic derivation from pseudo random seed
|
|
|
|
seedBuf = nacl.encode_latin1(util.base642Str(seed));
|
|
|
|
|
|
|
|
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))
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-04-04 15:36:29 -04:00
|
|
|
} else {
|
2013-04-29 09:10:27 -04:00
|
|
|
// generate keypiar from random values
|
2013-04-05 11:56:47 -04:00
|
|
|
keys = nacl.crypto_box_keypair();
|
|
|
|
|
2013-04-29 09:10:27 -04:00
|
|
|
callback({
|
|
|
|
id: util.UUID(),
|
|
|
|
boxPk: util.str2Base64(nacl.decode_latin1(keys.boxPk)),
|
|
|
|
boxSk: util.str2Base64(nacl.decode_latin1(keys.boxSk))
|
|
|
|
});
|
|
|
|
}
|
2013-04-04 15:36:29 -04:00
|
|
|
};
|
|
|
|
|
2013-04-10 11:09:39 -04:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
};
|
|
|
|
|
2013-04-04 15:36:29 -04:00
|
|
|
/**
|
|
|
|
* Asymmetrically encrypt a String
|
2013-04-04 08:28:07 -04:00
|
|
|
* @param plaintext [String] The input string in UTF8
|
2013-04-10 11:09:39 -04:00
|
|
|
* @param nonce [String] The base64 encoded nonce
|
2013-04-11 03:46:22 -04:00
|
|
|
* @param recipientPk [String] The receiver's base64 encoded public key
|
|
|
|
* @param senderSk [String] The sender's base64 encoded private key
|
2013-04-11 09:02:24 -04:00
|
|
|
* @return [String] The base64 encoded ciphertext
|
2013-04-04 08:28:07 -04:00
|
|
|
*/
|
2013-04-11 09:02:24 -04:00
|
|
|
this.asymEncrypt = function(plaintext, nonce, recipientPk, senderSk, callback) {
|
2013-04-04 15:36:29 -04:00
|
|
|
// convert to Uint8Array
|
|
|
|
var ptBuf = nacl.encode_utf8(plaintext);
|
2013-04-11 03:46:22 -04:00
|
|
|
var recipientPkBuf = nacl.encode_latin1(util.base642Str(recipientPk));
|
|
|
|
var senderSkBuf = nacl.encode_latin1(util.base642Str(senderSk));
|
2013-04-10 11:09:39 -04:00
|
|
|
var nonceBuf = nacl.encode_latin1(util.base642Str(nonce));
|
2013-04-04 08:28:07 -04:00
|
|
|
|
2013-04-11 09:02:24 -04:00
|
|
|
if (Worker) {
|
|
|
|
|
|
|
|
var worker = new Worker(app.config.workerPath + '/crypto/nacl-worker.js');
|
|
|
|
worker.onmessage = function(e) {
|
|
|
|
// encode to base64
|
|
|
|
callback(util.str2Base64(nacl.decode_latin1(e.data)));
|
|
|
|
};
|
|
|
|
worker.postMessage({
|
|
|
|
type: 'encrypt',
|
|
|
|
plaintext: ptBuf,
|
|
|
|
nonce: nonceBuf,
|
|
|
|
recipientPk: recipientPkBuf,
|
|
|
|
senderSk: senderSkBuf
|
|
|
|
});
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// encrypt
|
|
|
|
var ct = nacl.crypto_box(ptBuf, nonceBuf, recipientPkBuf, senderSkBuf);
|
|
|
|
// encode to base64
|
|
|
|
callback(util.str2Base64(nacl.decode_latin1(ct)));
|
|
|
|
}
|
2013-04-04 08:28:07 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-04-04 15:36:29 -04:00
|
|
|
* Asymmetrically decrypt a String
|
2013-04-04 08:28:07 -04:00
|
|
|
* @param ciphertext [String] The base64 encoded ciphertext
|
2013-04-04 15:36:29 -04:00
|
|
|
* @param nonce [String] The base64 encoded nonce
|
2013-04-11 03:46:22 -04:00
|
|
|
* @param senderPk [String] The sender's base64 encoded public key
|
|
|
|
* @param recipientSk [String] The receiver's base64 encoded private key
|
2013-04-04 08:28:07 -04:00
|
|
|
* @return [String] The decrypted plaintext in UTF8
|
|
|
|
*/
|
2013-04-11 09:02:24 -04:00
|
|
|
this.asymDecrypt = function(ciphertext, nonce, senderPk, recipientSk, callback) {
|
2013-04-04 15:36:29 -04:00
|
|
|
// convert to Uint8Array
|
2013-04-05 11:43:41 -04:00
|
|
|
var ctBuf = nacl.encode_latin1(util.base642Str(ciphertext));
|
|
|
|
var nonceBuf = nacl.encode_latin1(util.base642Str(nonce));
|
2013-04-11 03:46:22 -04:00
|
|
|
var senderPkBuf = nacl.encode_latin1(util.base642Str(senderPk));
|
|
|
|
var recipientSkBuf = nacl.encode_latin1(util.base642Str(recipientSk));
|
2013-04-10 04:51:03 -04:00
|
|
|
|
2013-04-11 09:02:24 -04:00
|
|
|
if (Worker) {
|
|
|
|
|
|
|
|
var worker = new Worker(app.config.workerPath + '/crypto/nacl-worker.js');
|
|
|
|
worker.onmessage = function(e) {
|
|
|
|
// decode to string
|
|
|
|
callback(nacl.decode_utf8(e.data));
|
|
|
|
};
|
|
|
|
worker.postMessage({
|
|
|
|
type: 'decrypt',
|
|
|
|
ciphertext: ctBuf,
|
|
|
|
nonce: nonceBuf,
|
|
|
|
senderPk: senderPkBuf,
|
|
|
|
recipienSk: recipientSkBuf
|
|
|
|
});
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// decrypt
|
|
|
|
var pt = nacl.crypto_box_open(ctBuf, nonceBuf, senderPkBuf, recipientSkBuf);
|
|
|
|
// decode to string
|
|
|
|
callback(nacl.decode_utf8(pt));
|
|
|
|
}
|
2013-04-10 04:51:03 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-04-11 09:02:24 -04:00
|
|
|
* Asymmetrically encrypt a String
|
2013-04-10 04:51:03 -04:00
|
|
|
* @param plaintext [String] The input string in UTF8
|
2013-04-10 11:09:39 -04:00
|
|
|
* @param nonce [String] The base64 encoded nonce
|
2013-04-11 09:02:24 -04:00
|
|
|
* @param recipientPk [String] The receiver's base64 encoded public key
|
|
|
|
* @param senderSk [String] The sender's base64 encoded private key
|
|
|
|
* @return [String] The base64 encoded ciphertext
|
2013-04-10 04:51:03 -04:00
|
|
|
*/
|
2013-04-11 09:02:24 -04:00
|
|
|
this.asymEncryptSync = function(plaintext, nonce, recipientPk, senderSk) {
|
2013-04-10 04:51:03 -04:00
|
|
|
// convert to Uint8Array
|
|
|
|
var ptBuf = nacl.encode_utf8(plaintext);
|
2013-04-11 09:02:24 -04:00
|
|
|
var recipientPkBuf = nacl.encode_latin1(util.base642Str(recipientPk));
|
|
|
|
var senderSkBuf = nacl.encode_latin1(util.base642Str(senderSk));
|
2013-04-10 11:09:39 -04:00
|
|
|
var nonceBuf = nacl.encode_latin1(util.base642Str(nonce));
|
2013-04-10 04:51:03 -04:00
|
|
|
// encrypt
|
2013-04-11 09:02:24 -04:00
|
|
|
var ct = nacl.crypto_box(ptBuf, nonceBuf, recipientPkBuf, senderSkBuf);
|
2013-04-10 04:51:03 -04:00
|
|
|
// encode to base64
|
|
|
|
var ctBase64 = util.str2Base64(nacl.decode_latin1(ct));
|
|
|
|
|
2013-04-10 11:09:39 -04:00
|
|
|
return ctBase64;
|
2013-04-10 04:51:03 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-04-11 09:02:24 -04:00
|
|
|
* Asymmetrically decrypt a String
|
2013-04-10 04:51:03 -04:00
|
|
|
* @param ciphertext [String] The base64 encoded ciphertext
|
|
|
|
* @param nonce [String] The base64 encoded nonce
|
2013-04-11 09:02:24 -04:00
|
|
|
* @param senderPk [String] The sender's base64 encoded public key
|
|
|
|
* @param recipientSk [String] The receiver's base64 encoded private key
|
2013-04-10 04:51:03 -04:00
|
|
|
* @return [String] The decrypted plaintext in UTF8
|
|
|
|
*/
|
2013-04-11 09:02:24 -04:00
|
|
|
this.asymDecryptSync = function(ciphertext, nonce, senderPk, recipientSk) {
|
2013-04-10 04:51:03 -04:00
|
|
|
// convert to Uint8Array
|
|
|
|
var ctBuf = nacl.encode_latin1(util.base642Str(ciphertext));
|
|
|
|
var nonceBuf = nacl.encode_latin1(util.base642Str(nonce));
|
2013-04-11 09:02:24 -04:00
|
|
|
var senderPkBuf = nacl.encode_latin1(util.base642Str(senderPk));
|
|
|
|
var recipientSkBuf = nacl.encode_latin1(util.base642Str(recipientSk));
|
2013-04-10 04:51:03 -04:00
|
|
|
// decrypt
|
2013-04-11 09:02:24 -04:00
|
|
|
var pt = nacl.crypto_box_open(ctBuf, nonceBuf, senderPkBuf, recipientSkBuf);
|
2013-04-10 04:51:03 -04:00
|
|
|
// decode to string
|
2013-04-04 15:36:29 -04:00
|
|
|
var ptStr = nacl.decode_utf8(pt);
|
2013-04-04 08:28:07 -04:00
|
|
|
|
2013-04-04 15:36:29 -04:00
|
|
|
return ptStr;
|
2013-04-04 08:28:07 -04:00
|
|
|
};
|
|
|
|
|
2013-04-05 11:43:41 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
|
|
module.exports = NaclCrypto;
|
|
|
|
} else {
|
|
|
|
app.crypto.NaclCrypto = NaclCrypto;
|
|
|
|
}
|