1
0
mirror of https://github.com/moparisthebest/mail synced 2024-12-01 21:32:17 -05:00

refactored crypto libto use different namespace

This commit is contained in:
Tankred Hase 2013-05-22 17:03:54 +02:00
parent f5d505df49
commit 487ddca28c
17 changed files with 479 additions and 469 deletions

View File

@ -15,8 +15,8 @@
var i = e.data, var i = e.data,
output = null, output = null,
aes = new app.crypto.AesCBC(forge), aes = new cryptoLib.AesCBC(forge),
batch = new app.crypto.CryptoBatch(aes); batch = new cryptoLib.CryptoBatch(aes);
if (i.type === 'encrypt' && i.list) { if (i.type === 'encrypt' && i.list) {
// start encryption // start encryption

View File

@ -1,51 +1,57 @@
/** (function() {
* A Wrapper for Forge's AES-CBC encryption
*/
var AesCBC = function(forge) {
'use strict'; 'use strict';
var utl = forge.util;
/** /**
* Encrypt a String using AES-CBC-Pkcs7 using the provided keysize (e.g. 128, 256) * A Wrapper for Forge's AES-CBC encryption
* @param plaintext [String] The input string in UTF-16
* @param key [String] The base64 encoded key
* @param iv [String] The base64 encoded IV
* @return [String] The base64 encoded ciphertext
*/ */
this.encrypt = function(plaintext, key, iv) { var AesCBC = function(forge) {
// decode args to utf8 and encrypt
var cipher = forge.aes.createEncryptionCipher(utl.decode64(key)); var utl = forge.util;
cipher.start(utl.decode64(iv));
cipher.update(utl.createBuffer(utl.encodeUtf8(plaintext))); /**
cipher.finish(); * Encrypt a String using AES-CBC-Pkcs7 using the provided keysize (e.g. 128, 256)
* @param plaintext [String] The input string in UTF-16
* @param key [String] The base64 encoded key
* @param iv [String] The base64 encoded IV
* @return [String] The base64 encoded ciphertext
*/
this.encrypt = function(plaintext, key, iv) {
// decode args to utf8 and encrypt
var cipher = forge.aes.createEncryptionCipher(utl.decode64(key));
cipher.start(utl.decode64(iv));
cipher.update(utl.createBuffer(utl.encodeUtf8(plaintext)));
cipher.finish();
// encode to base64
return utl.encode64(cipher.output.getBytes());
};
/**
* Decrypt a String using AES-CBC-Pkcs7 using the provided keysize (e.g. 128, 256)
* @param ciphertext [String] The base64 encoded ciphertext
* @param key [String] The base64 encoded key
* @param iv [String] The base64 encoded IV
* @return [String] The decrypted plaintext in UTF-16
*/
this.decrypt = function(ciphertext, key, iv) {
// decode args input to utf8 decrypt
var cipher = forge.aes.createDecryptionCipher(utl.decode64(key));
cipher.start(utl.decode64(iv));
cipher.update(utl.createBuffer(utl.decode64(ciphertext)));
cipher.finish();
// decode to utf16
return utl.decodeUtf8(cipher.output.getBytes());
};
// encode to base64
return utl.encode64(cipher.output.getBytes());
}; };
/** if (typeof module !== 'undefined' && module.exports) {
* Decrypt a String using AES-CBC-Pkcs7 using the provided keysize (e.g. 128, 256) module.exports = AesCBC;
* @param ciphertext [String] The base64 encoded ciphertext } else {
* @param key [String] The base64 encoded key var that = (typeof window !== 'undefined') ? window : self;
* @param iv [String] The base64 encoded IV that.cryptoLib = that.cryptoLib || {};
* @return [String] The decrypted plaintext in UTF-16 that.cryptoLib.AesCBC = AesCBC;
*/ }
this.decrypt = function(ciphertext, key, iv) {
// decode args input to utf8 decrypt
var cipher = forge.aes.createDecryptionCipher(utl.decode64(key));
cipher.start(utl.decode64(iv));
cipher.update(utl.createBuffer(utl.decode64(ciphertext)));
cipher.finish();
// decode to utf16 })();
return utl.decodeUtf8(cipher.output.getBytes());
};
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = AesCBC;
} else {
app.crypto.AesCBC = AesCBC;
}

View File

@ -14,7 +14,7 @@
var i = e.data, var i = e.data,
output = null, output = null,
aes = new app.crypto.AesCBC(forge); aes = new cryptoLib.AesCBC(forge);
if (i.type === 'encrypt' && i.plaintext && i.key && i.iv) { if (i.type === 'encrypt' && i.plaintext && i.key && i.iv) {
// start encryption // start encryption

View File

@ -17,10 +17,10 @@
var i = e.data, var i = e.data,
output = null, output = null,
aes = new app.crypto.AesCBC(forge), aes = new cryptoLib.AesCBC(forge),
rsa = new app.crypto.RSA(forge), rsa = new cryptoLib.RSA(forge),
util = new app.crypto.Util(), util = new cryptoLib.Util(),
batch = new app.crypto.CryptoBatch(aes, rsa, util); batch = new cryptoLib.CryptoBatch(aes, rsa, util);
// pass RSA keys to module // pass RSA keys to module
rsa.init(i.pubkeyPem, i.privkeyPem); rsa.init(i.pubkeyPem, i.privkeyPem);

View File

@ -1,91 +1,97 @@
/** (function() {
* Crypto batch library for processing large sets of data
*/
var CryptoBatch = function(aes, rsa, util) {
'use strict'; 'use strict';
/** /**
* Encrypt a list of items using AES * Crypto batch library for processing large sets of data
* @list list [Array] The list of items to encrypt
*/ */
this.encryptList = function(list) { var CryptoBatch = function(aes, rsa, util) {
list.forEach(function(i) {
// stringify to JSON before encryption
i.ciphertext = aes.encrypt(JSON.stringify(i.plaintext), i.key, i.iv);
delete i.plaintext;
});
return list; /**
}; * Encrypt a list of items using AES
* @list list [Array] The list of items to encrypt
*/
this.encryptList = function(list) {
list.forEach(function(i) {
// stringify to JSON before encryption
i.ciphertext = aes.encrypt(JSON.stringify(i.plaintext), i.key, i.iv);
delete i.plaintext;
});
/** return list;
* Decrypt a list of items using AES };
* @list list [Array] The list of items to decrypt
*/
this.decryptList = function(list) {
list.forEach(function(i) {
// decrypt JSON and parse to object literal
i.plaintext = JSON.parse(aes.decrypt(i.ciphertext, i.key, i.iv));
delete i.ciphertext;
});
return list; /**
}; * Decrypt a list of items using AES
* @list list [Array] The list of items to decrypt
*/
this.decryptList = function(list) {
list.forEach(function(i) {
// decrypt JSON and parse to object literal
i.plaintext = JSON.parse(aes.decrypt(i.ciphertext, i.key, i.iv));
delete i.ciphertext;
});
/** return list;
* Encrypt and sign a list of items using AES and RSA };
* @list list [Array] The list of items to encrypt
*/
this.encryptListForUser = function(list) {
// encrypt list
var encryptedList = this.encryptList(list);
// encrypt keys for user /**
encryptedList.forEach(function(i) { * Encrypt and sign a list of items using AES and RSA
// process new values * @list list [Array] The list of items to encrypt
i.encryptedKey = rsa.encrypt(i.key); */
i.signature = rsa.sign([i.iv, util.str2Base64(i.id), i.encryptedKey, i.ciphertext]); this.encryptListForUser = function(list) {
// delete old ones // encrypt list
delete i.key; var encryptedList = this.encryptList(list);
});
return encryptedList; // encrypt keys for user
}; encryptedList.forEach(function(i) {
// process new values
i.encryptedKey = rsa.encrypt(i.key);
i.signature = rsa.sign([i.iv, util.str2Base64(i.id), i.encryptedKey, i.ciphertext]);
// delete old ones
delete i.key;
});
/** return encryptedList;
* Decrypt and verify a list of items using AES and RSA };
* @list list [Array] The list of items to decrypt
*/
this.decryptListForUser = function(encryptedList) {
var j, self = this;
// decrypt keys for user /**
encryptedList.forEach(function(i) { * Decrypt and verify a list of items using AES and RSA
// verify signature * @list list [Array] The list of items to decrypt
if (!rsa.verify([i.iv, util.str2Base64(i.id), i.encryptedKey, i.ciphertext], i.signature)) { */
throw new Error('Verifying RSA signature failed!'); this.decryptListForUser = function(encryptedList) {
var j, self = this;
// decrypt keys for user
encryptedList.forEach(function(i) {
// verify signature
if (!rsa.verify([i.iv, util.str2Base64(i.id), i.encryptedKey, i.ciphertext], i.signature)) {
throw new Error('Verifying RSA signature failed!');
}
// precoess new values
i.key = rsa.decrypt(i.encryptedKey);
// delete old values
delete i.signature;
delete i.encryptedKey;
});
// decrypt list
var decryptedList = this.decryptList(encryptedList);
// add plaintext to list
for (j = 0; j < decryptedList.length; j++) {
decryptedList[j] = decryptedList[j].plaintext;
} }
// precoess new values
i.key = rsa.decrypt(i.encryptedKey);
// delete old values
delete i.signature;
delete i.encryptedKey;
});
// decrypt list return decryptedList;
var decryptedList = this.decryptList(encryptedList); };
// add plaintext to list
for (j = 0; j < decryptedList.length; j++) {
decryptedList[j] = decryptedList[j].plaintext;
}
return decryptedList;
}; };
};
if (typeof module !== 'undefined' && module.exports) { if (typeof module !== 'undefined' && module.exports) {
module.exports = CryptoBatch; module.exports = CryptoBatch;
} else { } else {
app.crypto.CryptoBatch = CryptoBatch; var that = (typeof window !== 'undefined') ? window : self;
} that.cryptoLib = that.cryptoLib || {};
that.cryptoLib.CryptoBatch = CryptoBatch;
}
})();

View File

@ -5,8 +5,8 @@
app.crypto.Crypto = function(window, util) { app.crypto.Crypto = function(window, util) {
'use strict'; 'use strict';
var aes = new app.crypto.AesCBC(forge); // use AES-CBC mode by default var aes = new cryptoLib.AesCBC(forge); // use AES-CBC mode by default
var rsa = new app.crypto.RSA(forge, util); // use RSA for asym. crypto var rsa = new cryptoLib.RSA(forge, util); // use RSA for asym. crypto
var keyStore = new app.dao.LocalStorageDAO(window); var keyStore = new app.dao.LocalStorageDAO(window);
var storageId; // storage id for the encrypted keypair in local storage var storageId; // storage id for the encrypted keypair in local storage
@ -232,7 +232,7 @@ app.crypto.Crypto = function(window, util) {
}); });
} else { } else {
var batch = new app.crypto.CryptoBatch(aes); var batch = new cryptoLib.CryptoBatch(aes);
var encryptedList = batch.encryptList(list); var encryptedList = batch.encryptList(list);
callback(encryptedList); callback(encryptedList);
} }
@ -251,7 +251,7 @@ app.crypto.Crypto = function(window, util) {
}); });
} else { } else {
var batch = new app.crypto.CryptoBatch(aes); var batch = new cryptoLib.CryptoBatch(aes);
var decryptedList = batch.decryptList(list); var decryptedList = batch.decryptList(list);
callback(decryptedList); callback(decryptedList);
} }
@ -292,7 +292,7 @@ app.crypto.Crypto = function(window, util) {
}); });
} else { } else {
var batch = new app.crypto.CryptoBatch(aes, rsa, util); var batch = new cryptoLib.CryptoBatch(aes, rsa, util);
var encryptedList = batch.encryptListForUser(envelopes); var encryptedList = batch.encryptListForUser(envelopes);
callback(null, encryptedList); callback(null, encryptedList);
} }
@ -315,7 +315,7 @@ app.crypto.Crypto = function(window, util) {
}); });
} else { } else {
var batch = new app.crypto.CryptoBatch(aes, rsa, util); var batch = new cryptoLib.CryptoBatch(aes, rsa, util);
var decryptedList = batch.decryptListForUser(list); var decryptedList = batch.decryptListForUser(list);
callback(null, decryptedList); callback(null, decryptedList);
} }

View File

@ -1,132 +1,138 @@
/** (function() {
* A Wrapper for Forge's RSA encryption
*/
var RSA = function(forge, util) {
'use strict'; 'use strict';
var utl = forge.util;
var keypair = {};
/** /**
* Initializes the RSA module by passing the user's keypair * A Wrapper for Forge's RSA encryption
* The private key is option and required only for decryption
* and signing
*/ */
this.init = function(pubkeyPem, privkeyPem, keyId) { var RSA = function(forge, util) {
if (pubkeyPem) {
keypair.publicKey = forge.pki.publicKeyFromPem(pubkeyPem);
}
if (privkeyPem) {
keypair.privateKey = forge.pki.privateKeyFromPem(privkeyPem);
}
if (keyId) {
keypair._id = keyId;
}
};
/** var utl = forge.util;
* Generate RSA keypair with the corresponding keysize
*/ var keypair = {};
this.generateKeypair = function(keySize, callback) {
forge.rsa.generateKeyPair({ /**
bits: keySize, * Initializes the RSA module by passing the user's keypair
workerScript: (typeof app !== 'undefined') ? (app.config.workerPath + '/../lib/forge/prime.worker.js') : undefined * The private key is option and required only for decryption
}, function(err, newKeypair) { * and signing
if (err || !newKeypair || !newKeypair.publicKey || !newKeypair.privateKey) { */
callback({ this.init = function(pubkeyPem, privkeyPem, keyId) {
errMsg: 'RSA keygeneration failed!', if (pubkeyPem) {
err: err keypair.publicKey = forge.pki.publicKeyFromPem(pubkeyPem);
});
return;
} }
if (privkeyPem) {
keypair.privateKey = forge.pki.privateKeyFromPem(privkeyPem);
}
if (keyId) {
keypair._id = keyId;
}
};
keypair = newKeypair; /**
// generate unique keypair ID * Generate RSA keypair with the corresponding keysize
keypair._id = util.UUID(); */
this.generateKeypair = function(keySize, callback) {
forge.rsa.generateKeyPair({
bits: keySize,
workerScript: (typeof app !== 'undefined') ? (app.config.workerPath + '/../lib/forge/prime.worker.js') : undefined
}, function(err, newKeypair) {
if (err || !newKeypair || !newKeypair.publicKey || !newKeypair.privateKey) {
callback({
errMsg: 'RSA keygeneration failed!',
err: err
});
return;
}
callback(null, { keypair = newKeypair;
// generate unique keypair ID
keypair._id = util.UUID();
callback(null, {
_id: keypair._id,
pubkeyPem: forge.pki.publicKeyToPem(keypair.publicKey),
privkeyPem: forge.pki.privateKeyToPem(keypair.privateKey)
});
});
};
/**
* Exports user's keypair as PEMs
*/
this.exportKeys = function() {
return {
_id: keypair._id, _id: keypair._id,
pubkeyPem: forge.pki.publicKeyToPem(keypair.publicKey), pubkeyPem: forge.pki.publicKeyToPem(keypair.publicKey),
privkeyPem: forge.pki.privateKeyToPem(keypair.privateKey) privkeyPem: forge.pki.privateKeyToPem(keypair.privateKey)
}); };
});
};
/**
* Exports user's keypair as PEMs
*/
this.exportKeys = function() {
return {
_id: keypair._id,
pubkeyPem: forge.pki.publicKeyToPem(keypair.publicKey),
privkeyPem: forge.pki.privateKeyToPem(keypair.privateKey)
}; };
/**
* Encrypt a String using RSA with PKCS#1 v1.5 padding
* @param plaintext [String] The input string in UTF-16
* @return [String] The base64 encoded ciphertext
*/
this.encrypt = function(plaintext) {
// encode plaintext to utf8 and encrypt
var ct = keypair.publicKey.encrypt(utl.encodeUtf8(plaintext));
// encode ciphtext to base64
return utl.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 UTF-16
*/
this.decrypt = function(ciphertext) {
// decode base64 ciphertext to utf8
var ctUtf8 = utl.decode64(ciphertext);
// decrypt and decode to utf16
return utl.decodeUtf8(keypair.privateKey.decrypt(ctUtf8));
};
/**
* Signs an Array of Base64 encoded parts with the private key
* @param parts [Array] Array of Base64 encoded parts
* @return [String] The Base64 encoded signature
*/
this.sign = function(parts) {
var sha = forge.md.sha256.create();
parts.forEach(function(i) {
// decode base64 part and append to sha msg
sha.update(utl.decode64(i));
});
// encode signature to base64
return utl.encode64(keypair.privateKey.sign(sha));
};
/**
* Verifies an Array of Base64 encoded parts with the public key
* @param parts [Array] Array of Base64 encoded parts
* @param sig [String] The Base64 encoded signatrure
* @return [bool] if the verification was successful
*/
this.verify = function(parts, sig) {
// decode base64 signature to utf8
var sigUtf8 = utl.decode64(sig);
var sha = forge.md.sha256.create();
parts.forEach(function(i) {
// decode base64 part and append to sha msg
sha.update(utl.decode64(i));
});
return keypair.publicKey.verify(sha.digest().getBytes(), sigUtf8);
};
}; };
/** if (typeof module !== 'undefined' && module.exports) {
* Encrypt a String using RSA with PKCS#1 v1.5 padding module.exports = RSA;
* @param plaintext [String] The input string in UTF-16 } else {
* @return [String] The base64 encoded ciphertext var that = (typeof window !== 'undefined') ? window : self;
*/ that.cryptoLib = that.cryptoLib || {};
this.encrypt = function(plaintext) { that.cryptoLib.RSA = RSA;
// encode plaintext to utf8 and encrypt }
var ct = keypair.publicKey.encrypt(utl.encodeUtf8(plaintext));
// encode ciphtext to base64
return utl.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 UTF-16
*/
this.decrypt = function(ciphertext) {
// decode base64 ciphertext to utf8
var ctUtf8 = utl.decode64(ciphertext);
// decrypt and decode to utf16
return utl.decodeUtf8(keypair.privateKey.decrypt(ctUtf8));
};
/**
* Signs an Array of Base64 encoded parts with the private key
* @param parts [Array] Array of Base64 encoded parts
* @return [String] The Base64 encoded signature
*/
this.sign = function(parts) {
var sha = forge.md.sha256.create();
parts.forEach(function(i) {
// decode base64 part and append to sha msg
sha.update(utl.decode64(i));
});
// encode signature to base64
return utl.encode64(keypair.privateKey.sign(sha));
};
/**
* Verifies an Array of Base64 encoded parts with the public key
* @param parts [Array] Array of Base64 encoded parts
* @param sig [String] The Base64 encoded signatrure
* @return [bool] if the verification was successful
*/
this.verify = function(parts, sig) {
// decode base64 signature to utf8
var sigUtf8 = utl.decode64(sig);
var sha = forge.md.sha256.create();
parts.forEach(function(i) {
// decode base64 part and append to sha msg
sha.update(utl.decode64(i));
});
return keypair.publicKey.verify(sha.digest().getBytes(), sigUtf8);
};
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = RSA;
} else {
app.crypto.RSA = RSA;
}

View File

@ -1,203 +1,209 @@
/** (function() {
* Various utitity methods for crypto, encoding & decoding
*/
var Util = function(window, uuid, crypt) {
'use strict'; 'use strict';
/** /**
* Generates a new RFC 4122 version 4 compliant random UUID * Various utitity methods for crypto, encoding & decoding
*/ */
this.UUID = function() { var Util = function(window, uuid, crypt) {
return uuid.v4();
};
/** /**
* Generates a cryptographically secure random base64-encoded key or IV * Generates a new RFC 4122 version 4 compliant random UUID
* @param keySize [Number] The size of the key in bits (e.g. 128, 256) */
* @return [String] The base64 encoded key/IV this.UUID = function() {
*/ return uuid.v4();
this.random = function(keySize) { };
var keyBase64, keyBuf;
/**
if (typeof module !== 'undefined' && module.exports) { * Generates a cryptographically secure random base64-encoded key or IV
// node.js * @param keySize [Number] The size of the key in bits (e.g. 128, 256)
keyBuf = crypt.randomBytes(keySize / 8); * @return [String] The base64 encoded key/IV
keyBase64 = new Buffer(keyBuf).toString('base64'); */
this.random = function(keySize) {
} else if (window.crypto && window.crypto.getRandomValues) { var keyBase64, keyBuf;
// browser if secure rng exists
keyBuf = new Uint8Array(keySize / 8); if (typeof module !== 'undefined' && module.exports) {
window.crypto.getRandomValues(keyBuf); // node.js
keyBase64 = window.btoa(this.uint8Arr2BinStr(keyBuf)); keyBuf = crypt.randomBytes(keySize / 8);
keyBase64 = new Buffer(keyBuf).toString('base64');
} else {
// generate random bytes with fortuna algorithm from forge } else if (window.crypto && window.crypto.getRandomValues) {
keyBase64 = window.btoa(forge.random.getBytesSync(keySize / 8)); // browser if secure rng exists
} keyBuf = new Uint8Array(keySize / 8);
window.crypto.getRandomValues(keyBuf);
return keyBase64; keyBase64 = window.btoa(this.uint8Arr2BinStr(keyBuf));
};
} else {
/** // generate random bytes with fortuna algorithm from forge
* Parse a date string with the following format "1900-01-31 18:17:53" keyBase64 = window.btoa(forge.random.getBytesSync(keySize / 8));
*/ }
this.parseDate = function(str) {
var parts = str.match(/(\d+)/g); return keyBase64;
return new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]); };
};
/**
/** * Parse a date string with the following format "1900-01-31 18:17:53"
* Returns a string representation of a date in the format "1900-01-31 18:17:53" */
*/ this.parseDate = function(str) {
this.formatDate = function(date) { var parts = str.match(/(\d+)/g);
var year = "" + date.getFullYear(); return new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
var month = "" + (date.getMonth() + 1); };
if (month.length == 1) {
month = "0" + month; /**
} * Returns a string representation of a date in the format "1900-01-31 18:17:53"
var day = "" + date.getDate(); */
if (day.length == 1) { this.formatDate = function(date) {
day = "0" + day; var year = "" + date.getFullYear();
} var month = "" + (date.getMonth() + 1);
var hour = "" + date.getHours(); if (month.length == 1) {
if (hour.length == 1) { month = "0" + month;
hour = "0" + hour; }
} var day = "" + date.getDate();
var minute = "" + date.getMinutes(); if (day.length == 1) {
if (minute.length == 1) { day = "0" + day;
minute = "0" + minute; }
} var hour = "" + date.getHours();
var second = "" + date.getSeconds(); if (hour.length == 1) {
if (second.length == 1) { hour = "0" + hour;
second = "0" + second; }
} var minute = "" + date.getMinutes();
return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second; if (minute.length == 1) {
}; minute = "0" + minute;
}
/** var second = "" + date.getSeconds();
* Converts a binary String (e.g. from the FileReader Api) to an ArrayBuffer if (second.length == 1) {
* @param str [String] a binary string with integer values (0..255) per character second = "0" + second;
* @return [ArrayBuffer] }
*/ return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
this.binStr2ArrBuf = function(str) { };
var b = new ArrayBuffer(str.length);
var buf = new Uint8Array(b); /**
* Converts a binary String (e.g. from the FileReader Api) to an ArrayBuffer
for (var i = 0; i < b.byteLength; i++) { * @param str [String] a binary string with integer values (0..255) per character
buf[i] = str.charCodeAt(i); * @return [ArrayBuffer]
} */
this.binStr2ArrBuf = function(str) {
return b; var b = new ArrayBuffer(str.length);
}; var buf = new Uint8Array(b);
/** for (var i = 0; i < b.byteLength; i++) {
* Creates a Blob from an ArrayBuffer using the BlobBuilder Api buf[i] = str.charCodeAt(i);
* @param str [String] a binary string with integer values (0..255) per character }
* @return [ArrayBuffer] either a data url or a filesystem url
*/ return b;
this.arrBuf2Blob = function(buf, mimeType) { };
var b = new Uint8Array(buf);
var blob = new Blob([b], { /**
type: mimeType * Creates a Blob from an ArrayBuffer using the BlobBuilder Api
}); * @param str [String] a binary string with integer values (0..255) per character
* @return [ArrayBuffer] either a data url or a filesystem url
return blob; */
}; this.arrBuf2Blob = function(buf, mimeType) {
var b = new Uint8Array(buf);
/** var blob = new Blob([b], {
* Creates a binary String from a Blob using the FileReader Api type: mimeType
* @param blob [Blob/File] a blob containing the the binary data });
* @return [String] a binary string with integer values (0..255) per character
*/ return blob;
this.blob2BinStr = function(blob, callback) { };
var reader = new FileReader();
/**
reader.onload = function(event) { * Creates a binary String from a Blob using the FileReader Api
callback(event.target.result); * @param blob [Blob/File] a blob containing the the binary data
* @return [String] a binary string with integer values (0..255) per character
*/
this.blob2BinStr = function(blob, callback) {
var reader = new FileReader();
reader.onload = function(event) {
callback(event.target.result);
};
reader.readAsBinaryString(blob);
};
/**
* Converts an ArrayBuffer to a binary String. This is a slower alternative to
* conversion with arrBuf2Blob -> blob2BinStr, since these use native apis,
* but it can be used on browsers without the BlodBuilder Api
* @param buf [ArrayBuffer]
* @return [String] a binary string with integer values (0..255) per character
*/
this.arrBuf2BinStr = function(buf) {
var b = new Uint8Array(buf);
var str = '';
for (var i = 0; i < b.length; i++) {
str += String.fromCharCode(b[i]);
}
return str;
};
/**
* Converts a UInt8Array to a binary String.
* @param buf [UInt8Array]
* @return [String] a binary string with integer values (0..255) per character
*/
this.uint8Arr2BinStr = function(buf) {
var str = '';
for (var i = 0; i < buf.length; i++) {
str += String.fromCharCode(buf[i]);
}
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
*/
this.str2Base64 = function(str) {
if (typeof module !== 'undefined' && module.exports) {
return new Buffer(str, 'binary').toString('base64');
} else if (typeof window !== 'undefined' && window.btoa) {
return window.btoa(str);
} else {
return forge.util.encode64(str);
}
};
/**
* Convert a base64 encoded string in a browser and in node.js
*/
this.base642Str = function(str) {
if (typeof module !== 'undefined' && module.exports) {
return new Buffer(str, 'base64').toString('binary');
} else if (typeof window !== 'undefined' && window.atob) {
return window.atob(str);
} else {
return forge.util.decode64(str);
}
}; };
reader.readAsBinaryString(blob);
}; };
/** if (typeof module !== 'undefined' && module.exports) {
* Converts an ArrayBuffer to a binary String. This is a slower alternative to module.exports = Util;
* conversion with arrBuf2Blob -> blob2BinStr, since these use native apis, } else {
* but it can be used on browsers without the BlodBuilder Api var that = (typeof window !== 'undefined') ? window : self;
* @param buf [ArrayBuffer] that.cryptoLib = that.cryptoLib || {};
* @return [String] a binary string with integer values (0..255) per character that.cryptoLib.Util = Util;
*/ }
this.arrBuf2BinStr = function(buf) {
var b = new Uint8Array(buf);
var str = '';
for (var i = 0; i < b.length; i++) { })();
str += String.fromCharCode(b[i]);
}
return str;
};
/**
* Converts a UInt8Array to a binary String.
* @param buf [UInt8Array]
* @return [String] a binary string with integer values (0..255) per character
*/
this.uint8Arr2BinStr = function(buf) {
var str = '';
for (var i = 0; i < buf.length; i++) {
str += String.fromCharCode(buf[i]);
}
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
*/
this.str2Base64 = function(str) {
if (typeof module !== 'undefined' && module.exports) {
return new Buffer(str, 'binary').toString('base64');
} else if (typeof window !== 'undefined' && window.btoa) {
return window.btoa(str);
} else {
return forge.util.encode64(str);
}
};
/**
* Convert a base64 encoded string in a browser and in node.js
*/
this.base642Str = function(str) {
if (typeof module !== 'undefined' && module.exports) {
return new Buffer(str, 'base64').toString('binary');
} else if (typeof window !== 'undefined' && window.atob) {
return window.atob(str);
} else {
return forge.util.decode64(str);
}
};
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = Util;
} else {
app.crypto.Util = Util;
}

View File

@ -15,7 +15,7 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, util) {
var storedKey = crypto.getEncryptedPrivateKey(account.get('emailAddress')); var storedKey = crypto.getEncryptedPrivateKey(account.get('emailAddress'));
cloudstorage.syncPrivateKey(account.get('emailAddress'), storedKey, function(err) { cloudstorage.syncPrivateKey(account.get('emailAddress'), storedKey, function(err) {
if (err) { if (err) {
console.log('Error syncing secret key to cloud: ' + err); console.log('Error syncing private key to cloud: ' + err);
} }
// init crypto // init crypto
initCrypto(); initCrypto();

View File

@ -1,6 +1,6 @@
var TestData = function() { var TestData = function() {
var util = new app.crypto.Util(window, uuid); var util = new cryptoLib.Util(window, uuid);
this.getEmailCollection = function(size) { this.getEmailCollection = function(size) {
// create test data // create test data

View File

@ -2,12 +2,12 @@ module("AES Crypto");
var aes_test = { var aes_test = {
keySize: 128, keySize: 128,
util: new app.crypto.Util(window, uuid), util: new cryptoLib.Util(window, uuid),
test_message: new TestData().generateBigString(1000) test_message: new TestData().generateBigString(1000)
}; };
test("CBC mode", 4, function() { test("CBC mode", 4, function() {
var aes = new app.crypto.AesCBC(forge); var aes = new cryptoLib.AesCBC(forge);
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);
@ -21,17 +21,3 @@ test("CBC mode", 4, function() {
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);
}); });
// test("CCM mode", 2, function() {
// var aes = new app.crypto.AesCCM(sjcl);
// var plaintext = aes_test.test_message;
// var key = aes_test.util.random(aes_test.keySize);
// var iv = aes_test.util.random(104);
// var ciphertext = aes.encrypt(plaintext, key, iv);
// ok(ciphertext, 'Ciphertext length: ' + ciphertext.length);
// var decrypted = aes.decrypt(ciphertext, key, iv);
// equal(decrypted, plaintext, 'Decryption correct: ' + decrypted);
// });

View File

@ -10,7 +10,7 @@ var crypto_test = {
asyncTest("Init", 2, function() { asyncTest("Init", 2, function() {
// init dependencies // init dependencies
crypto_test.util = new app.crypto.Util(window, uuid); crypto_test.util = new cryptoLib.Util(window, uuid);
crypto_test.crypto = new app.crypto.Crypto(window, crypto_test.util); crypto_test.crypto = new app.crypto.Crypto(window, crypto_test.util);
ok(crypto_test.crypto, 'Crypto'); ok(crypto_test.crypto, 'Crypto');

View File

@ -10,7 +10,7 @@ var devicestorage_test = {
asyncTest("Init", 3, function() { asyncTest("Init", 3, function() {
// init dependencies // init dependencies
devicestorage_test.util = new app.crypto.Util(window, uuid); devicestorage_test.util = new cryptoLib.Util(window, uuid);
devicestorage_test.jsonDao = new app.dao.LawnchairDAO(window); devicestorage_test.jsonDao = new app.dao.LawnchairDAO(window);
devicestorage_test.crypto = new app.crypto.Crypto(window, devicestorage_test.util); devicestorage_test.crypto = new app.crypto.Crypto(window, devicestorage_test.util);
devicestorage_test.storage = new app.dao.DeviceStorage(devicestorage_test.util, devicestorage_test.crypto, devicestorage_test.jsonDao, null); devicestorage_test.storage = new app.dao.DeviceStorage(devicestorage_test.util, devicestorage_test.crypto, devicestorage_test.jsonDao, null);

View File

@ -10,7 +10,7 @@ var emaildao_test = {
asyncTest("Init", 3, function() { asyncTest("Init", 3, function() {
// init dependencies // init dependencies
var util = new app.crypto.Util(window, uuid); var util = new cryptoLib.Util(window, uuid);
var jsonDao = new app.dao.LawnchairDAO(window); var jsonDao = new app.dao.LawnchairDAO(window);
emaildao_test.crypto = new app.crypto.Crypto(window, util); emaildao_test.crypto = new app.crypto.Crypto(window, util);
emaildao_test.storage = new app.dao.DeviceStorage(util, emaildao_test.crypto, jsonDao, null); emaildao_test.storage = new app.dao.DeviceStorage(util, emaildao_test.crypto, jsonDao, null);

View File

@ -25,7 +25,7 @@ test("SHA-256 Hash", 1, function() {
}); });
test("HMAC SHA-256", 1, function() { test("HMAC SHA-256", 1, function() {
var util = new app.crypto.Util(window, uuid); var util = new cryptoLib.Util(window, uuid);
var key = util.base642Str(util.random(forge_aes_test.keySize)); var key = util.base642Str(util.random(forge_aes_test.keySize));
var iv = util.base642Str(util.random(forge_aes_test.keySize)); var iv = util.base642Str(util.random(forge_aes_test.keySize));

View File

@ -2,7 +2,7 @@ module("RSA Crypto");
var rsa_test = { var rsa_test = {
keySize: 1024, keySize: 1024,
rsa: new app.crypto.RSA(forge, new app.crypto.Util(window, uuid)), rsa: new cryptoLib.RSA(forge, new cryptoLib.Util(window, uuid)),
test_message: '06a9214036b8a15b512e03d534120006' test_message: '06a9214036b8a15b512e03d534120006'
}; };

View File

@ -11,14 +11,14 @@ test("JQuery and basic requirements", 7, function() {
}); });
test("UUID", 2, function() { test("UUID", 2, function() {
var util = new app.crypto.Util(window, uuid); var util = new cryptoLib.Util(window, uuid);
var id = util.UUID(); var id = util.UUID();
ok(id, "UUID: " + id); ok(id, "UUID: " + id);
ok(id.length === 36, "UUID length"); ok(id.length === 36, "UUID length");
}); });
test("random", 3, function() { test("random", 3, function() {
var util = new app.crypto.Util(window, uuid); var util = new cryptoLib.Util(window, uuid);
var base64 = util.random(128); var base64 = util.random(128);
var str = window.atob(base64); var str = window.atob(base64);
ok(base64, "Random base64: " + base64); ok(base64, "Random base64: " + base64);
@ -27,7 +27,7 @@ test("random", 3, function() {
}); });
test("Parse Date", 1, function() { test("Parse Date", 1, function() {
var util = new app.crypto.Util(window, uuid); var util = new cryptoLib.Util(window, uuid);
var str = '1900-01-31 18:17:53'; var str = '1900-01-31 18:17:53';
var date = util.parseDate(str); var date = util.parseDate(str);
var formated = util.formatDate(date); var formated = util.formatDate(date);
@ -35,7 +35,7 @@ test("Parse Date", 1, function() {
}); });
test("String -> Uint8Array -> String", 3, function() { test("String -> Uint8Array -> String", 3, function() {
var util = new app.crypto.Util(window); var util = new cryptoLib.Util(window);
var input = "asdf"; var input = "asdf";
var buf = util.binStr2Uint8Arr(input); var buf = util.binStr2Uint8Arr(input);