From ec0685829ee5fdcac0ce7bb364aebb268fd10836 Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Thu, 4 Apr 2013 21:36:29 +0200 Subject: [PATCH] implemented asymmetric nacl crypto and unit test --- src/js/crypto/nacl-crypto.js | 61 +++++++++++++++++++++++++------ src/test/unit/nacl-crypto-test.js | 29 ++++++--------- 2 files changed, 62 insertions(+), 28 deletions(-) diff --git a/src/js/crypto/nacl-crypto.js b/src/js/crypto/nacl-crypto.js index 661f967..64829cc 100644 --- a/src/js/crypto/nacl-crypto.js +++ b/src/js/crypto/nacl-crypto.js @@ -5,25 +5,64 @@ app.crypto.NaclCrypto = function() { 'use strict'; /** - * Encrypt a String with the provided keysize (e.g. 128, 256) - * @param plaintext [String] The input string in UTF8 - * @param key [String] The base64 encoded key - * @param iv [String] The base64 encoded IV - * @return [String] The base64 encoded ciphertext + * Generates a baes64 encoded keypair for use with NaCl */ - this.encrypt = function(plaintext, key, iv) { - + this.generateKeypair = function(seed) { + if (seed) { + return null; // TODO: generate from PBKDF2 + } else { + var keys = nacl.crypto_box_keypair(); + return { + boxPk: window.btoa(nacl.decode_latin1(keys.boxPk)), + boxSk: window.btoa(nacl.decode_latin1(keys.boxSk)) + }; + } }; /** - * Decrypt a String with the provided keysize (e.g. 128, 256) + * Asymmetrically encrypt a String + * @param plaintext [String] The input string in UTF8 + * @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) { + // convert to Uint8Array + var ptBuf = nacl.encode_utf8(plaintext); + var recipientBoxPkBuf = nacl.encode_latin1(window.atob(recipientBoxPk)); + var senderBoxSkBuf = nacl.encode_latin1(window.atob(senderBoxSk)); + // generate nonce + var nonce = nacl.crypto_secretbox_random_nonce(); + + var ct = nacl.crypto_box(ptBuf, nonce, recipientBoxPkBuf, senderBoxSkBuf); + var ctBase64 = window.btoa(nacl.decode_latin1(ct)); + var nonceBase64 = window.btoa(nacl.decode_latin1(nonce)); + + return { + ct: ctBase64, + nonce: nonceBase64 + }; + }; + + /** + * Asymmetrically decrypt a String * @param ciphertext [String] The base64 encoded ciphertext - * @param key [String] The base64 encoded key - * @param iv [String] The base64 encoded IV + * @param nonce [String] The base64 encoded nonce + * @param senderBoxPk [String] The sender's base64 encoded public key + * @param recipientBoxSk [String] The receiver's base64 encoded private key * @return [String] The decrypted plaintext in UTF8 */ - this.decrypt = function(ciphertext, key, iv) { + this.asymmetricDecrypt = function(ciphertext, nonce, senderBoxPk, recipientBoxSk) { + // convert to Uint8Array + var ctBuf = nacl.encode_latin1(window.atob(ciphertext)); + var nonceBuf = nacl.encode_latin1(window.atob(nonce)); + var senderBoxPkBuf = nacl.encode_latin1(window.atob(senderBoxPk)); + var recipientBoxSkBuf = nacl.encode_latin1(window.atob(recipientBoxSk)); + var pt = nacl.crypto_box_open(ctBuf, nonceBuf, senderBoxPkBuf, recipientBoxSkBuf); + var ptStr = nacl.decode_utf8(pt); + + return ptStr; }; }; \ No newline at end of file diff --git a/src/test/unit/nacl-crypto-test.js b/src/test/unit/nacl-crypto-test.js index 01c46af..52bb870 100644 --- a/src/test/unit/nacl-crypto-test.js +++ b/src/test/unit/nacl-crypto-test.js @@ -10,33 +10,28 @@ test("Init", 1, function() { ok(nacl_test.util, 'Util'); // generate test data nacl_test.test_message = new TestData().generateBigString(1000); + nacl_test.crypto = new app.crypto.NaclCrypto(); }); -test("Generate Keypiar", 1, function() { +test("Generate Keypair", 2, function() { // generate keypair from seed - var keys = nacl.crypto_box_keypair(); - ok(keys.boxSk && keys.boxPk, "Keysize: " + keys.boxPk.length); - nacl_test.keys = keys; + 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.senderKeypair = senderKeypair; + nacl_test.recipientKeypair = recipientKeypair; }); test("En/Decrypt", 2, function() { - var naclCrypto = new app.crypto.NaclCrypto(); - var plaintext = nacl_test.test_message; - // var key = nacl_test.util.random(nacl_test.keySize); - // var iv = nacl_test.util.random(104); - // convert utf8 string to Uint8Array - var pt = nacl.encode_utf8(plaintext); - // generate nonce - var nonce = nacl.crypto_secretbox_random_nonce(); // encrypt - var ct = nacl.crypto_secretbox(pt, nonce, nacl_test.keys.boxSk); - ok(ct, 'Ciphertext length: ' + ct.length); + 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); // decrypt - var decryptedBuf = nacl.crypto_secretbox_open(ct, nonce, nacl_test.keys.boxSk); - var decrypted = nacl.decode_utf8(decryptedBuf); + var decrypted = nacl_test.crypto.asymmetricDecrypt(ct.ct, ct.nonce, nacl_test.senderKeypair.boxPk, nacl_test.recipientKeypair.boxSk); equal(decrypted, plaintext, 'Decryption correct: ' + decrypted); - }); \ No newline at end of file