made util, nacl and aes crossplatform

This commit is contained in:
Tankred Hase 2013-04-05 17:43:41 +02:00
parent 84c9abcd36
commit 21aad0afb2
9 changed files with 71 additions and 47 deletions

View File

@ -20,7 +20,7 @@
var args = e.data, var args = e.data,
output = null, output = null,
aes = new app.crypto.AesCCM(), aes = new app.crypto.AesCCM(sjcl),
util = new app.crypto.Util(null, null); util = new app.crypto.Util(null, null);
if (args.type === 'encrypt' && args.list) { if (args.type === 'encrypt' && args.list) {

View File

@ -1,7 +1,7 @@
/** /**
* A Wrapper for SJCL's authenticated AES-CCM encryption * A Wrapper for SJCL's authenticated AES-CCM encryption
*/ */
app.crypto.AesCCM = function() { var AesCCM = function(sjcl) {
'use strict'; 'use strict';
var adata = []; // authenticated data (empty by default) var adata = []; // authenticated data (empty by default)
@ -47,4 +47,10 @@ app.crypto.AesCCM = function() {
return pt; return pt;
}; };
}; };
if (typeof module !== 'undefined' && module.exports) {
module.exports = AesCCM;
} else {
app.crypto.AesCCM = AesCCM;
}

View File

@ -19,7 +19,7 @@
var args = e.data, var args = e.data,
output = null, output = null,
aes = new app.crypto.AesCCM(); aes = new app.crypto.AesCCM(sjcl);
if (args.type === 'encrypt' && args.plaintext && args.key && args.iv) { if (args.type === 'encrypt' && args.plaintext && args.key && args.iv) {
// start encryption // start encryption

View File

@ -6,7 +6,7 @@ app.crypto.Crypto = function(window, util) {
'use strict'; 'use strict';
var symmetricUserKey, // the user's secret key used to encrypt item-keys var symmetricUserKey, // the user's secret key used to encrypt item-keys
aes = new app.crypto.AesCCM(); // use authenticated AES-CCM mode by default aes = new app.crypto.AesCCM(sjcl); // use authenticated AES-CCM mode by default
/** /**
* Initializes the crypto modules by fetching the user's * Initializes the crypto modules by fetching the user's

View File

@ -1,7 +1,7 @@
/** /**
* A Wrapper for NaCl's asymmetric/symmetric crypto * A Wrapper for NaCl's asymmetric/symmetric crypto
*/ */
app.crypto.NaclCrypto = function() { var NaclCrypto = function(util) {
'use strict'; 'use strict';
/** /**
@ -13,8 +13,8 @@ app.crypto.NaclCrypto = function() {
} else { } else {
var keys = nacl.crypto_box_keypair(); var keys = nacl.crypto_box_keypair();
return { return {
boxPk: window.btoa(nacl.decode_latin1(keys.boxPk)), boxPk: util.str2Base64(nacl.decode_latin1(keys.boxPk)),
boxSk: window.btoa(nacl.decode_latin1(keys.boxSk)) boxSk: util.str2Base64(nacl.decode_latin1(keys.boxSk))
}; };
} }
}; };
@ -29,14 +29,14 @@ app.crypto.NaclCrypto = function() {
this.asymmetricEncrypt = function(plaintext, recipientBoxPk, senderBoxSk) { this.asymmetricEncrypt = function(plaintext, recipientBoxPk, senderBoxSk) {
// convert to Uint8Array // convert to Uint8Array
var ptBuf = nacl.encode_utf8(plaintext); var ptBuf = nacl.encode_utf8(plaintext);
var recipientBoxPkBuf = nacl.encode_latin1(window.atob(recipientBoxPk)); var recipientBoxPkBuf = nacl.encode_latin1(util.base642Str(recipientBoxPk));
var senderBoxSkBuf = nacl.encode_latin1(window.atob(senderBoxSk)); var senderBoxSkBuf = nacl.encode_latin1(util.base642Str(senderBoxSk));
// generate nonce // generate nonce
var nonce = nacl.crypto_secretbox_random_nonce(); var nonce = nacl.crypto_secretbox_random_nonce();
var ct = nacl.crypto_box(ptBuf, nonce, recipientBoxPkBuf, senderBoxSkBuf); var ct = nacl.crypto_box(ptBuf, nonce, recipientBoxPkBuf, senderBoxSkBuf);
var ctBase64 = window.btoa(nacl.decode_latin1(ct)); var ctBase64 = util.str2Base64(nacl.decode_latin1(ct));
var nonceBase64 = window.btoa(nacl.decode_latin1(nonce)); var nonceBase64 = util.str2Base64(nacl.decode_latin1(nonce));
return { return {
ct: ctBase64, ct: ctBase64,
@ -54,10 +54,10 @@ app.crypto.NaclCrypto = function() {
*/ */
this.asymmetricDecrypt = function(ciphertext, nonce, senderBoxPk, recipientBoxSk) { this.asymmetricDecrypt = function(ciphertext, nonce, senderBoxPk, recipientBoxSk) {
// convert to Uint8Array // convert to Uint8Array
var ctBuf = nacl.encode_latin1(window.atob(ciphertext)); var ctBuf = nacl.encode_latin1(util.base642Str(ciphertext));
var nonceBuf = nacl.encode_latin1(window.atob(nonce)); var nonceBuf = nacl.encode_latin1(util.base642Str(nonce));
var senderBoxPkBuf = nacl.encode_latin1(window.atob(senderBoxPk)); var senderBoxPkBuf = nacl.encode_latin1(util.base642Str(senderBoxPk));
var recipientBoxSkBuf = nacl.encode_latin1(window.atob(recipientBoxSk)); var recipientBoxSkBuf = nacl.encode_latin1(util.base642Str(recipientBoxSk));
var pt = nacl.crypto_box_open(ctBuf, nonceBuf, senderBoxPkBuf, recipientBoxSkBuf); var pt = nacl.crypto_box_open(ctBuf, nonceBuf, senderBoxPkBuf, recipientBoxSkBuf);
var ptStr = nacl.decode_utf8(pt); var ptStr = nacl.decode_utf8(pt);
@ -65,4 +65,10 @@ app.crypto.NaclCrypto = function() {
return ptStr; return ptStr;
}; };
}; };
if (typeof module !== 'undefined' && module.exports) {
module.exports = NaclCrypto;
} else {
app.crypto.NaclCrypto = NaclCrypto;
}

View File

@ -172,6 +172,22 @@ var Util = function(window, uuid) {
return str; return str;
}; };
/**
* Converts a binary String (e.g. from the FileReader Api) to a UInt8Array
* @param str [String] a binary string with integer values (0..255) per character
* @return [UInt8Array]
*/
this.binStr2Uint8Arr = function(str) {
var c, buf = new Uint8Array(str.length);
for (var i = 0; i < buf.length; i++) {
c = str.charCodeAt(i);
buf[i] = (c & 0xff);
}
return buf;
};
/** /**
* Convert a str to base64 in a browser and in node.js * Convert a str to base64 in a browser and in node.js
*/ */

View File

@ -29,15 +29,15 @@ test("CBC mode", 4, function() {
}); });
test("CCM mode", 2, function() { test("CCM mode", 2, function() {
var aes = new app.crypto.AesCCM(); var aes = new app.crypto.AesCCM(sjcl);
var plaintext = aes_test.test_message; var plaintext = aes_test.test_message;
var key = aes_test.util.random(aes_test.keySize); var key = aes_test.util.random(aes_test.keySize);
var iv = aes_test.util.random(104); var iv = aes_test.util.random(104);
var ciphertext = aes.encrypt(plaintext, key, iv); var ciphertext = aes.encrypt(plaintext, key, iv);
ok(ciphertext, 'Ciphertext length: ' + ciphertext.length); ok(ciphertext, 'Ciphertext length: ' + ciphertext.length);
var decrypted = aes.decrypt(ciphertext, key, iv); var decrypted = aes.decrypt(ciphertext, key, iv);
equal(decrypted, plaintext, 'Decryption correct: ' + decrypted); equal(decrypted, plaintext, 'Decryption correct: ' + decrypted);
}); });

View File

@ -6,13 +6,19 @@ var nacl_test = {
test("Init", 1, function() { test("Init", 1, function() {
// init dependencies // init dependencies
nacl_test.util = new app.crypto.Util(window, uuid); var util = new app.crypto.Util(window, uuid);
ok(nacl_test.util, 'Util'); ok(util, 'Util');
// generate test data // generate test data
nacl_test.test_message = new TestData().generateBigString(1000); nacl_test.test_message = new TestData().generateBigString(1000);
nacl_test.crypto = new app.crypto.NaclCrypto(); nacl_test.crypto = new app.crypto.NaclCrypto(util);
}); });
// test("Generate Keypair from seed", 2, function() {
// // generate keypair from seed
// var keys = nacl_test.crypto.generateKeypair();
// ok(keys.boxSk && keys.boxPk, "Keypair: " + JSON.stringify(keys));
// });
test("Generate Keypair", 2, function() { test("Generate Keypair", 2, function() {
// generate keypair from seed // generate keypair from seed
var senderKeypair = nacl_test.crypto.generateKeypair(); var senderKeypair = nacl_test.crypto.generateKeypair();

View File

@ -1,13 +1,13 @@
module("Util"); module("Util");
test("JQuery and basic requirements", 7, function() { test("JQuery and basic requirements", 7, function() {
ok( Array.prototype.push, "Array.push()" ); ok(Array.prototype.push, "Array.push()");
ok( Function.prototype.apply, "Function.apply()" ); ok(Function.prototype.apply, "Function.apply()");
ok( document.getElementById, "getElementById" ); ok(document.getElementById, "getElementById");
ok( document.getElementsByTagName, "getElementsByTagName" ); ok(document.getElementsByTagName, "getElementsByTagName");
ok( RegExp, "RegExp" ); ok(RegExp, "RegExp");
ok( jQuery, "jQuery" ); ok(jQuery, "jQuery");
ok( $, "$" ); ok($, "$");
}); });
test("UUID", 2, function() { test("UUID", 2, function() {
@ -32,25 +32,15 @@ test("Parse Date", 1, function() {
ok(date, "Date: " + date); ok(date, "Date: " + date);
}); });
test("String -> ArrayBuffer -> String", 3, function() { test("String -> Uint8Array -> String", 3, function() {
var util = new app.crypto.Util(window); var util = new app.crypto.Util(window);
var input = "asdf"; var input = "asdf";
var buf = util.binStr2ArrBuf(input); var buf = util.binStr2Uint8Arr(input);
ok(buf); ok(buf);
// test slow conversion in js // test slow conversion in js
var binStr = util.arrBuf2BinStr(buf); var binStr = util.uint8Arr2BinStr(buf);
ok(binStr); ok(binStr);
equal(binStr, input); equal(binStr, input);
});
// // test native conversion with BlobBuilder Api
// var blob = util.arrBuf2Blob(buf, 'application/octet-stream');
// ok(blob);
//
// util.blob2BinStr(blob, function(output) {
// equal(output, input);
//
// start();
// });
});