diff --git a/src/js/crypto/aes-cbc.js b/src/js/crypto/aes-cbc.js
index 7d109e8..41ceb38 100644
--- a/src/js/crypto/aes-cbc.js
+++ b/src/js/crypto/aes-cbc.js
@@ -30,7 +30,6 @@ app.crypto.AesCBC = function(forge) {
* @param ciphertext [String] The base64 encoded ciphertext
* @param key [String] The base64 encoded key
* @param iv [String] The base64 encoded IV
- * @param iv [String] The base64 encoded HMAC
* @return [String] The decrypted plaintext in UTF8
*/
this.decrypt = function(ciphertext, key, iv) {
diff --git a/src/js/crypto/rsa.js b/src/js/crypto/rsa.js
new file mode 100644
index 0000000..2f73fdd
--- /dev/null
+++ b/src/js/crypto/rsa.js
@@ -0,0 +1,94 @@
+/**
+ * A Wrapper for Forge's RSA encryption
+ */
+app.crypto.RSA = function(forge) {
+ 'use strict';
+
+ var publicKey = null,
+ privateKey = null;
+
+ /**
+ * Initializes the RSA module by passing the user's keypair
+ * The private key is option and required only for decryption
+ * and signing
+ */
+ this.init = function(pubkeyPem, privkeyPem) {
+ publicKey = forge.pki.publicKeyFromPem(pubkeyPem);
+ if (privkeyPem) {
+ privateKey = forge.pki.privateKeyFromPem(privkeyPem);
+ }
+ };
+
+ /**
+ * Generate RSA keypair with the corresponding keysize
+ */
+ this.generateKeypair = function(keySize, callback) {
+ forge.rsa.generateKeyPair({
+ bits: keySize,
+ workerScript: app.config.workerPath + '/../../lib/forge/prime.worker.js'
+ }, function(err, keypair) {
+ if (err || !keypair.publicKey || !keypair.privateKey) {
+ callback({
+ errMsg: 'RSA keygeneration failed!',
+ err: err
+ });
+ return;
+ }
+
+ publicKey = keypair.publicKey;
+ privateKey = keypair.privateKey;
+
+ callback();
+ });
+ };
+
+ /**
+ * Exports user's keypair as PEMs
+ */
+ this.exportKeys = function() {
+ return {
+ pubkeyPem: forge.pki.publicKeyToPem(publicKey),
+ privkeyPem: forge.pki.privateKeyToPem(privateKey)
+ };
+ };
+
+ /**
+ * Encrypt a String using RSA with PKCS#1 v1.5 padding
+ * @param plaintext [String] The input string in UTF8
+ * @return [String] The base64 encoded ciphertext
+ */
+ this.encrypt = function(plaintext) {
+ var ct = publicKey.encrypt(plaintext);
+ return forge.util.encode64(ct);
+ };
+
+ /**
+ * Decrypt a String using RSA with PKCS#1 v1.5 padding
+ * @param ciphertext [String] The base64 encoded ciphertext
+ * @return [String] The decrypted plaintext in UTF8
+ */
+ this.decrypt = function(ciphertext) {
+ // parse base64 input to utf8
+ var ctUtf8 = forge.util.decode64(ciphertext);
+ return privateKey.decrypt(ctUtf8);
+ };
+
+ this.sign = function(input) {
+ var sha = forge.md.sha256.create();
+ sha.update(input);
+
+ var sig = privateKey.sign(sha);
+ return forge.util.encode64(sig);
+ };
+
+ this.verify = function(input, sig) {
+ // parse base64 signature to utf8
+ var sigUtf8 = forge.util.decode64(sig);
+
+ var sha = forge.md.sha256.create();
+ sha.update(input);
+
+ return publicKey.verify(sha.digest().getBytes(), sigUtf8);
+ };
+
+};
\ No newline at end of file
diff --git a/test/unit/aes-test.js b/test/unit/aes-test.js
index 57c3706..bf4609d 100644
--- a/test/unit/aes-test.js
+++ b/test/unit/aes-test.js
@@ -1,17 +1,11 @@
module("AES Crypto");
var aes_test = {
- keySize: 128
+ keySize: 128,
+ util: new app.crypto.Util(window, uuid),
+ test_message: new TestData().generateBigString(1000)
};
-test("Init", 1, function() {
- // init dependencies
- aes_test.util = new app.crypto.Util(window, uuid);
- ok(aes_test.util, 'Util');
- // generate test data
- aes_test.test_message = new TestData().generateBigString(1000);
-});
-
test("CBC mode", 4, function() {
var aes = new app.crypto.AesCBC(forge);
diff --git a/test/unit/forge-test.js b/test/unit/forge-test.js
index 60c3e34..65306ec 100644
--- a/test/unit/forge-test.js
+++ b/test/unit/forge-test.js
@@ -1,6 +1,6 @@
module("Forge Crypto");
-var rsa_test = {
+var forge_rsa_test = {
keySize: 1024,
test_message: '06a9214036b8a15b512e03d534120006'
};
@@ -13,15 +13,15 @@ var forge_aes_test = {
test("SHA-1 Hash", 1, function() {
var sha1 = forge.md.sha1.create();
sha1.update(forge_aes_test.test_message);
- var digest = sha1.digest().getBytes();
- ok(digest);
+ var digest = sha1.digest().toHex();
+ ok(digest, digest);
});
test("SHA-256 Hash", 1, function() {
- rsa_test.md = forge.md.sha256.create();
- rsa_test.md.update(forge_aes_test.test_message);
- var digest = rsa_test.md.digest().getBytes();
- ok(digest);
+ forge_rsa_test.md = forge.md.sha256.create();
+ forge_rsa_test.md.update(forge_aes_test.test_message);
+ var digest = forge_rsa_test.md.digest().toHex();
+ ok(digest, digest);
});
test("HMAC SHA-256", 1, function() {
@@ -34,85 +34,7 @@ test("HMAC SHA-256", 1, function() {
hmac.start('sha256', key);
hmac.update(iv);
hmac.update(forge_aes_test.test_message);
- var result = hmac.digest().toHex();
+ var digest = hmac.digest().toHex();
- ok(result);
-});
-
-test("PBKDF2", 1, function() {
- var util = new app.crypto.Util(window, uuid);
-
- var salt = util.base642Str("vbhmLjC+Ub6MSbhS6/CkOwxB25wvwRkSLP2DzDtYb+4=");
- var expect = '5223bd44b0523090b21e9d38a749b090';
-
- var dk = forge.pkcs5.pbkdf2('password', salt, 1000, 16);
-
- equal(expect, forge.util.bytesToHex(dk));
-});
-
-asyncTest("RSA Generate Keypair", 1, function() {
-
- forge.rsa.generateKeyPair({
- bits: rsa_test.keySize,
- workerScript: app.config.workerPath + '/../lib/forge/prime.worker.js'
- }, function(err, keypair) {
- ok(!err && keypair);
-
- rsa_test.keypair = keypair;
-
- start();
- });
-
-});
-
-test("RSA Encrypt", 1, function() {
- rsa_test.ct = rsa_test.keypair.publicKey.encrypt(rsa_test.test_message);
- ok(rsa_test.ct);
-});
-
-test("RSA Decrypt", 1, function() {
- var pt = rsa_test.keypair.privateKey.decrypt(rsa_test.ct);
- equal(rsa_test.test_message, pt);
-});
-
-test("RSA Sign", 1, function() {
- var sha = forge.md.sha256.create();
- sha.update(forge_aes_test.test_message);
-
- rsa_test.sig = rsa_test.keypair.privateKey.sign(sha);
- ok(rsa_test.sig);
-});
-
-test("RSA Verify", 1, function() {
- var res = rsa_test.keypair.publicKey.verify(rsa_test.md.digest().getBytes(), rsa_test.sig);
- ok(res);
-});
-
-test("AES-128-CBC Encrypt", 1, function() {
- var util = new app.crypto.Util(window, uuid);
-
- forge_aes_test.key = util.base642Str(util.random(forge_aes_test.keySize));
- forge_aes_test.iv = util.base642Str(util.random(forge_aes_test.keySize));
- var input = forge_aes_test.test_message;
-
- // encrypt
- var enCipher = forge.aes.createEncryptionCipher(forge_aes_test.key);
- enCipher.start(forge_aes_test.iv);
- enCipher.update(forge.util.createBuffer(input));
- enCipher.finish();
-
- forge_aes_test.ct = enCipher.output.getBytes();
- ok(forge_aes_test.ct);
-});
-
-test("AES-128-CBC Decrypt", 1, function() {
- var input = forge_aes_test.test_message;
-
- // decrypt
- var deCipher = forge.aes.createDecryptionCipher(forge_aes_test.key);
- deCipher.start(forge_aes_test.iv);
- deCipher.update(forge.util.createBuffer(forge_aes_test.ct));
- deCipher.finish();
-
- equal(input, deCipher.output, 'En/Decrypt length: ' + input.length);
+ ok(digest, digest);
});
\ No newline at end of file
diff --git a/test/unit/index.html b/test/unit/index.html
index cd72b44..01f0e6b 100644
--- a/test/unit/index.html
+++ b/test/unit/index.html
@@ -42,6 +42,7 @@
+
@@ -56,6 +57,7 @@
+
diff --git a/test/unit/rsa-test.js b/test/unit/rsa-test.js
new file mode 100644
index 0000000..30620c2
--- /dev/null
+++ b/test/unit/rsa-test.js
@@ -0,0 +1,50 @@
+module("RSA Crypto");
+
+var rsa_test = {
+ keySize: 1024,
+ rsa: new app.crypto.RSA(forge),
+ test_message: '06a9214036b8a15b512e03d534120006'
+};
+
+asyncTest("Generate keypair", 1, function() {
+ rsa_test.rsa.generateKeypair(rsa_test.keySize, function(err) {
+ ok(!err);
+
+ start();
+ });
+});
+
+test("Export keys", 2, function() {
+ rsa_test.keypair = rsa_test.rsa.exportKeys();
+
+ ok(rsa_test.keypair.pubkeyPem.indexOf('-----BEGIN PUBLIC KEY-----') === 0, rsa_test.keypair.pubkeyPem);
+ ok(rsa_test.keypair.privkeyPem.indexOf('-----BEGIN RSA PRIVATE KEY-----') === 0, rsa_test.keypair.privkeyPem);
+});
+
+test("Init", 2, function() {
+ rsa_test.rsa.init(rsa_test.keypair.pubkeyPem, rsa_test.keypair.privkeyPem);
+ var exported = rsa_test.rsa.exportKeys();
+
+ ok(exported.pubkeyPem.indexOf('-----BEGIN PUBLIC KEY-----') === 0);
+ ok(exported.privkeyPem.indexOf('-----BEGIN RSA PRIVATE KEY-----') === 0);
+});
+
+test("Encrypt", 1, function() {
+ rsa_test.ct = rsa_test.rsa.encrypt(rsa_test.test_message);
+ ok(rsa_test.ct);
+});
+
+test("Decrypt", 1, function() {
+ var pt = rsa_test.rsa.decrypt(rsa_test.ct);
+ equal(pt, rsa_test.test_message);
+});
+
+test("Sign", 1, function() {
+ rsa_test.sig = rsa_test.rsa.sign(rsa_test.test_message);
+ ok(rsa_test.sig);
+});
+
+test("Verify", 1, function() {
+ var res = rsa_test.rsa.verify(rsa_test.test_message, rsa_test.sig);
+ ok(res);
+});
\ No newline at end of file