I have a written encryption method that uses CryptoJS and I have a 32-word long key and some string. I'm trying to send a message to a web service that requires the data to be AES encrypted with padding=PKCS7 and then converted to Base64. I did the following:
Function for encryption
export function encryptByAES(message: string, key: string): any {
let encryptedMessage: CryptoJS.WordArray = CryptoJS.AES.encrypt(
message,
key,
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}
);
return encryptedMessage;
}
function toBase64String(words : any) : any{
return CryptoJS.enc.Base64.stringify(words);
}
I use the function, and get above input:
let encry = encryptByAES(message, key);
console.log('Encrypted to string(): ' + encry.toString()); //Prints U2FsdGVkX19XZDGZBnr+dM6qJA6bfUpp1kmhSK6E0t6TeuJU78BkyUkIthWnnWnX99Q9Eeq0pbdLWlgTx576MIV9FDYDcjcajlApXr/6r9k=
let b64words = toBase64String(encry.ciphertext); //Prints zqokDpt9SmnWSaFIroTS3pN64lTvwGTJSQi2Faedadf31D0R6rSlt0taWBPHnvowhX0UNgNyNxqOUClev/qv2Q==
console.log('Ciphertext: ' + b64words);
By the '=' sign at the end, I see that both are Base64, but why they are different. The Encrypted to string has an extra part at the beginning 'U2FsdGVkX' (I assume that it's iv or something) and if I change the message It stays the same, but I thought the ciphertext would be a substring of Encrypted to string()?
EDIT:
the example key is:
const key = 'xxxxxxxxxxxxxxxxxxxxxxxxx ';
I've modified it because it's not public but it definitely got some special characters and two spaces at the end(letters upper and lower case, grater than 'f' etc.). IV was not specified, and I've got to use encoded message to connect with an API
My questions are:
As the necessary code can be better shown I'm using an answer and not the comment for the code line you should consider.
From the documentation (this code is for the default AES CBC mode) https://cryptojs.gitbook.io/docs/#custom-key-and-iv
custom-key-and-iv
var key = CryptoJS.enc.Hex.parse("000102030405060708090a0b0c0d0e0f");
var iv = CryptoJS.enc.Hex.parse("101112131415161718191a1b1c1d1e1f");
var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv });
Security warning: Kindly note that the ECB mode is unsecure.
Edit - to answer your questions:
How do I know that the string is Base64 encrypted for sure(It's on frontend(browser))? Use of the default output (resulting from "return encryptedMessage") is compatible to OpenSSL and that's base64 encoding.
Why string number 2(b64words) isn't substring of string number 1? Because it's doubled Base64-encoding and the string looks different.
Why I was able to decrypt string number 1 with CryptoJS, but no success with string number 2(b64words)? You would have success with string number 2 if you first base64-decode the string number 2 and feed the result to your decryption function.