I would start by reviewing the following link, please note the ciphertext = ....).toString()
- calling
encrypt.toString()
outputs the encryption already base64
encoded.
Then you will notice they immediately pass the output of ciphertext = ....).toString()
to the decryption.
https://github.com/brix/crypto-js#object-encryption
I am not sure the ramifications of using encrypt.ciphertext
I personally do not use it so I am not in a position to comment on it... but I do know that the output of the following is not the same... This would be something to investigate futher.
console.log(encrypted.toString())
console.log(CryptoJS.enc.Base64.stringify(encrypted.ciphertext))
Please note: I believe the decryption expects the ciphertext to be a base64
string... that is at least the case in my application.
I suspect encrypt.toString()
versus CryptoJS.enc.Base64.stringify(encrypted.ciphertext)
may be the start of your problem... but looking at your concatenation process I suspect there may be issues there as well.
You are generating a random initialization vector with each encryption so there should be a certain layer of obfuscation there... I would just base64
the IV
and concatenate it with a delimiting character like :
for example... something like this would make life a little easier during the decryption stage in terms of isolating the two... would be a lot easier to troubleshoot as well compared to what you are doing now.
This will result in iv:ciphertext
concatenated with a :
delimiter
both base64
... if you had concerns you could then base64
the output of this before you transmit it across the wire... not that it would make it secure... but it would at least be another layer of obfuscation.
btoa(iv)+':'+encrypted.toString()
I will say I think the splice may be a problem... looking at source and destination in the console log... I think the splice may need to be splice(4,4)
as those 4 indexes seem to be the ones you want... but again I am not too familiar with how you are attempting this part... so I will defer.
I know this is not a copy paste solution but I am hoping this will be enough information to get you where you need to go.
Revision
Hoping this is copy and paste... if it is it will be a working baseline you can modify as needed.
encryptPasswords(credentials: PasswordData) {
const password = credentials.password;
// msgString is expected to be Utf8 encoded
const key = CryptoJS.enc.Utf8.parse(utilities.localStorageHelper.LowLevelKey);
const iv = CryptoJS.lib.WordArray.random(16);
const encrypted = CryptoJS.AES.encrypt(password, key, {
iv: iv
});
return btoa(btoa(iv)+':'+encrypted.toString())
// return iv.concat(encrypted.ciphertext).toString(CryptoJS.enc.Base64);
}
decryptPasswords(credentials: PasswordData) {
/*
* Decrypt payload
* @param {string} ciphertextStr - Encrypted Payload
* @return {}
*/
const key = CryptoJS.enc.Utf8.parse(utilities.localStorageHelper.LowLevelKey);
// const ciphertext = CryptoJS.enc.Base64.parse(stringBase64);
const ciphertextArray = atob(stringBase64).split(':');
const iv = ciphertextArray[0];
const ciphertext = ciphertextArray[1]
// split IV and ciphertext
// const iv = ciphertext.clone();
// iv.sigBytes = 16;
// iv.clamp();
// ciphertext.words.splice(0, 4); // delete 4 words = 16 bytes
// ciphertext.sigBytes -= 16;
// decryption
const decrypted = CryptoJS.AES.decrypt(ciphertext, key, {
iv: iv
});
return decrypted.toString(CryptoJS.enc.Utf8);
}