mirror of
https://github.com/moparisthebest/mail
synced 2024-11-25 10:22:18 -05:00
added rsa module and tests
This commit is contained in:
parent
ec14639d56
commit
6bbcd8cab7
@ -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) {
|
||||
|
94
src/js/crypto/rsa.js
Normal file
94
src/js/crypto/rsa.js
Normal file
@ -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);
|
||||
};
|
||||
|
||||
};
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
});
|
@ -42,6 +42,7 @@
|
||||
<script src="../js/crypto/util.js"></script>
|
||||
<script src="../js/crypto/pbkdf2.js"></script>
|
||||
<script src="../js/crypto/aes-cbc.js"></script>
|
||||
<script src="../js/crypto/rsa.js"></script>
|
||||
<script src="../js/crypto/nacl-crypto.js"></script>
|
||||
<script src="../js/crypto/crypto.js"></script>
|
||||
|
||||
@ -56,6 +57,7 @@
|
||||
<script src="util-test.js"></script>
|
||||
<script src="forge-test.js"></script>
|
||||
<script src="aes-test.js"></script>
|
||||
<script src="rsa-test.js"></script>
|
||||
<script src="nacl-crypto-test.js"></script>
|
||||
<script src="crypto-test.js"></script>
|
||||
<script src="localstorage-dao-test.js"></script>
|
||||
|
50
test/unit/rsa-test.js
Normal file
50
test/unit/rsa-test.js
Normal file
@ -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);
|
||||
});
|
Loading…
Reference in New Issue
Block a user