Removed oboslete code from encryptionService and gave it a better layout.

This commit is contained in:
Brendon Duncan 2018-06-28 20:49:54 +12:00
commit 63ddf545e4

View file

@ -1,205 +1,146 @@
'use strict'; (function() {
'use strict';
angular.module('copayApp.services').factory('encryptionService', function($log, secureStorageService) {
var root = {};
var keySize = 512; angular.module('copayApp.services').factory('encryptionService', function($log, secureStorageService) {
var iterations = 1500; var keySize = 512;
var storageKey = 'encryptionKey'; var iterations = 1500;
var storageKey = 'encryptionKey';
// need a function to get the key var service = {
var password = 'password'; decrypt: decrypt,
encrypt: encrypt
};
return service;
function _generateKey() { function _generateKey() {
var salt = CryptoJS.lib.WordArray.random(128/8); var salt = CryptoJS.lib.WordArray.random(128/8);
var passphrase = CryptoJS.lib.WordArray.random(128/8); var passphrase = CryptoJS.lib.WordArray.random(128/8);
var key = CryptoJS.PBKDF2(passphrase, salt, { keySize: keySize/32, iterations: iterations }); var key = CryptoJS.PBKDF2(passphrase, salt, { keySize: keySize/32, iterations: iterations });
$log.debug('Generated key: ' + key); $log.debug('Generated key: ' + key);
return key; return key;
} }
/** /**
* *
* @param {*} cb * @param {*} cb
*/ */
function _getOrCreateKey(cb) { function _getOrCreateKey(cb) {
// TODO: Get from secure storage
secureStorageService.get(storageKey, function onKeyRetrieved(keyErr, keyHex) {
if (keyErr) {
cb(keyErr, null);
return;
}
if (keyHex) { secureStorageService.get(storageKey, function onKeyRetrieved(keyErr, keyHex) {
var key = CryptoJS.enc.Hex.parse(keyHex); if (keyErr) {
cb(null, key); cb(keyErr, null);
return;
}
key = _generateKey();
var keyHex = CryptoJS.enc.Hex.stringify(key);
secureStorageService.set(storageKey, keyHex, function onKeyStored(storeErr) {
if (storeErr) {
$log.error('Error storing key.', storeErr);
cb(storeErr, null);
return; return;
} }
cb(null, key); if (keyHex) {
var key = CryptoJS.enc.Hex.parse(keyHex);
cb(null, key);
return;
}
key = _generateKey();
var keyHex = CryptoJS.enc.Hex.stringify(key);
secureStorageService.set(storageKey, keyHex, function onKeyStored(storeErr) {
if (storeErr) {
$log.error('Error storing key.', storeErr);
cb(storeErr, null);
return;
}
cb(null, key);
});
}); });
});
};
/**
*
* @param {string, Base64 encoded} str
* @param {CryptoJS.WordArray} key
* @param {string, hex} iv
*/
function _decryptUsingCryptoJS(str, key, iv) {
$log.debug('decrypt() str: ' + str);
$log.debug('decrypt() using iv:' + iv + ', key: ' + JSON.stringify(key));
var ivWords = CryptoJS.enc.Hex.parse(iv);
var plaintext = CryptoJS.AES.decrypt(str, key, { iv: ivWords });
$log.debug('plaintext', JSON.stringify(plaintext));
var plaintextWords = CryptoJS.lib.WordArray.create();
plaintextWords.init(plaintext.words, plaintext.sigBytes);
$log.debug('plaintextWords', JSON.stringify(plaintextWords));
var plaintextString = plaintextWords.toString(CryptoJS.enc.Utf8);
$log.debug('plaintextString: ', JSON.stringify(plaintextString));
return plaintextString;
}
function _encryptUsingCryptoJS(str, key) {
$log.debug('encrypt() str: ' + str);
var iv = CryptoJS.lib.WordArray.random(16);
$log.debug('Encrypting profile: ', JSON.stringify(str));
var cipherParams = CryptoJS.AES.encrypt(str, key, { iv: iv });
var ciphertext = cipherParams.ciphertext.toString(CryptoJS.enc.Base64);
var iv = iv.toString(CryptoJS.enc.Hex);
$log.debug('ciphertext: ' + ciphertext);
$log.debug('iv: ' + iv);
// Just for testing - do we get back what we put in?
root.decrypt(ciphertext, {iv: iv}, function onDecryptionTest(err, decrypted){
if (err) {
$log.error('Failed to decrypt encrypted.', err);
} else {
$log.debug('Freshly decrypted:', JSON.stringify(decrypted));
}
});
return {
ciphertext: cipherParams.ciphertext.toString(CryptoJS.enc.Base64),
opts: {
iv: iv.toString(CryptoJS.enc.Hex)
}
}; };
}
root.decrypt = function(str, opts, cb) { /**
_getOrCreateKey(function onKey(err, key) { *
if (err) { * @param {string, Base64 encoded} str
$log.error('Failed to get or create key.', err); * @param {CryptoJS.WordArray} key
cb(err, null); * @param {string, hex} iv
return; */
} function _decryptUsingCryptoJS(str, key, iv) {
$log.debug('decrypt() str: ' + str);
$log.debug('decrypt() using iv:' + iv + ', key: ' + JSON.stringify(key));
var decrypted = _decryptUsingCryptoJS(str, key, opts.iv); var ivWords = CryptoJS.enc.Hex.parse(iv);
cb(null, decrypted); var plaintext = CryptoJS.AES.decrypt(str, key, { iv: ivWords });
}); $log.debug('plaintext', JSON.stringify(plaintext));
};
root.encrypt = function(str, cb) { var plaintextWords = CryptoJS.lib.WordArray.create();
$log.debug('encrypt()', JSON.stringify('str')); plaintextWords.init(plaintext.words, plaintext.sigBytes);
$log.debug('*** crypto exists: ' + !!crypto); $log.debug('plaintextWords', JSON.stringify(plaintextWords));
$log.debug('*** CryptoJS exists: ' + !!CryptoJS); var plaintextString = plaintextWords.toString(CryptoJS.enc.Utf8);
$log.debug('plaintextString: ', JSON.stringify(plaintextString));
_getOrCreateKey(function onKey(err, key){ return plaintextString;
if (err) {
cb(err, null);
return;
}
var encrypted = _encryptUsingCryptoJS(str, key);
cb(null, encrypted);
});
};
root.encryptedObjectFromString = function(str) {
try {
var parsed = JSON.parse(str);
} catch(e) {
return null;
} }
if (parsed.encryptionVersion) {
return parsed;
} else {
return null;
}
};
var JsonFormatter = { function _encryptUsingCryptoJS(str, key) {
stringify: function (cipherParams) { $log.debug('encrypt() str: ' + str);
// create json object with ciphertext var iv = CryptoJS.lib.WordArray.random(16);
var jsonObj = {
ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64) $log.debug('Encrypting profile: ', JSON.stringify(str));
};
// optionally add iv and salt var cipherParams = CryptoJS.AES.encrypt(str, key, { iv: iv });
if (cipherParams.iv) { var ciphertext = cipherParams.ciphertext.toString(CryptoJS.enc.Base64);
jsonObj.iv = cipherParams.iv.toString(); var iv = iv.toString(CryptoJS.enc.Hex);
} $log.debug('ciphertext: ' + ciphertext);
$log.debug('iv: ' + iv);
// Just for testing - do we get back what we put in?
decrypt(ciphertext, {iv: iv}, function onDecryptionTest(err, decrypted){
if (err) {
$log.error('Failed to decrypt encrypted.', err);
} else {
$log.debug('Freshly decrypted:', JSON.stringify(decrypted));
}
if (cipherParams.salt) {
jsonObj.s = cipherParams.salt.toString();
}
// stringify json object
return JSON.stringify(jsonObj);
},
parse: function (jsonStr) {
// parse json string
var jsonObj = JSON.parse(jsonStr);
// extract ciphertext from json object, and create cipher params object
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(jsonObj.ct)
}); });
// optionally extract iv and salt
if (jsonObj.iv) {
cipherParams.iv = CryptoJS.enc.Hex.parse(jsonObj.iv)
}
if (jsonObj.s) { return {
cipherParams.salt = CryptoJS.enc.Hex.parse(jsonObj.s) ciphertext: cipherParams.ciphertext.toString(CryptoJS.enc.Base64),
} opts: {
iv: iv.toString(CryptoJS.enc.Hex)
return cipherParams; }
};
} }
};
/* function decrypt(str, opts, cb) {
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase", { format: JsonFormatter }); _getOrCreateKey(function onKey(err, key) {
alert(encrypted); // {"ct":"tZ4MsEnfbcDOwqau68aOrQ==","iv":"8a8c8fd8fe33743d3638737ea4a00698","s":"ba06373c8f57179c"} if (err) {
$log.error('Failed to get or create key.', err);
cb(err, null);
return;
}
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase", { format: JsonFormatter }); var decrypted = _decryptUsingCryptoJS(str, key, opts.iv);
alert(decrypted.toString(CryptoJS.enc.Utf8)); // Message cb(null, decrypted);
*/ });
};
return root; function encrypt(str, cb) {
}); $log.debug('encrypt()', JSON.stringify('str'));
$log.debug('*** crypto exists: ' + !!crypto);
$log.debug('*** CryptoJS exists: ' + !!CryptoJS);
_getOrCreateKey(function onKey(err, key){
if (err) {
cb(err, null);
return;
}
var encrypted = _encryptUsingCryptoJS(str, key);
cb(null, encrypted);
});
};
});
})();