Reputation: 1638
Decryption works using php/openssl and I can get my plain data. Here is the defined call:
<?php
function decryptString($data, $key)
{
return base64_decode(openssl_decrypt(base64_decode($data), "AES-256-CBC", $key, true, "h7oehNIHWGNIHxyN"));
}
function encryptString($data, $key)
{
return base64_encode(openssl_encrypt(base64_encode($data), "AES-256-CBC", $key, true, "h7oehNIHWGNIHxyN"));
}
echo 'encrypted: ' . encryptString('my sample text', '7f7720b911c2ecbb22637ed7adef41e82d44b6a0') . "\n";
echo 'decrypted: ' . decryptString('rFWejB1Pj6W3Gh1bheFqDZPMO9POKbhGPOP6eAH9BSk=', '7f7720b911c2ecbb22637ed7adef41e82d44b6a0') . "\n";
and I get this output:
encrypted: rFWejB1Pj6W3Gh1bheFqDZPMO9POKbhGPOP6eAH9BSk=
decrypted: my sample text
I tried to implement this same function using cryptojs, but things are not working, and I get "Malformed UTF-8 data" sometimes and sometimes others ambiguous errors (Empty string / Canno't read property length of undefined depending on the code change I do). So here is the best I did so far: ( I have "Malformed UTF-8 data" error at the moment)
function decryptData(encrypted, pass) {
// encrypted is a base64 encoded string
let data = let data = Buffer.from(encrypted, "base64").toString(); // I tried this also [ let data = crypto.enc.Base64.parse(encrypted); ]
let key = crypto.enc.Utf8.parse(pass);
let decrypted = crypto.AES.decrypt(data, key,
{
iv: crypto.enc.Hex.parse('h7oehNIHWGNIHxyN'), // tried passing it as a simple string like this [ iv: 'h7oehNIHWGNIHxyN', ]
mode: crypto.mode.CBC,
padding: crypto.pad.NoPadding // I tried also with [ crypto.pad.Pkcs7 ]
}
);
let result = decrypted.toString(crypto.enc.Utf8); // tried this also [ let result = decrypted.toString(crypto.enc.Base64) ]
}
Here is the error I get:
/home/vagrant/PhpstormProjects/untitled3/node_modules/crypto-js/core.js:513
throw new Error('Malformed UTF-8 data');
^
Error: Malformed UTF-8 data
at Object.stringify (/home/vagrant/PhpstormProjects/untitled3/node_modules/crypto-js/core.js:513:24)
at WordArray.init.toString (/home/vagrant/PhpstormProjects/untitled3/node_modules/crypto-js/core.js:268:38)
at decodeBase64String (/home/vagrant/PhpstormProjects/untitled3/decryptor.js:13:25)
at Object.<anonymous> (/home/vagrant/PhpstormProjects/untitled3/decryptor.js:19:1)
This might seem pretty obvious but I feel confused, and nothing seems to work. Could you please help me out?
Questions I Tried to follow with no luck:
Update 1: I edited the question to add a sample plain message and full php encryption/decription example along with my last code's version.
Upvotes: 2
Views: 505
Reputation: 49296
AES is only defined for 16/24/32 bytes keys. You are using a 40 bytes key. PHP implicitly cuts the key to 32 bytes, CryptoJS does not, but processes the key without error message due to a bug (#293), with a wrong result, of course.
Also, the ciphertext must be passed as CipherParams
object or Base64 encoded, the IV must be Utf8 encoded, PKCS7 padding should be used, and the decrypted data is a base64 string (and still needs to be Base64 decoded).
The following CryptoJS code decrypts the sample ciphertext:
function decryptData(encrypted, pass) {
let decryptedWA = CryptoJS.AES.decrypt(
encrypted, // Pass ciphertext Base64 encoded (or as CipherParams object)
CryptoJS.enc.Utf8.parse(pass.substring(0, 32)), // Truncate key to 32 bytes
{
iv: CryptoJS.enc.Utf8.parse('h7oehNIHWGNIHxyN'), // UTF8 encode the IV
mode: CryptoJS.mode.CBC, // default
padding: CryptoJS.pad.Pkcs7 // default // Apply PKCS7 padding
}
);
let decryptedB64 = decryptedWA.toString(CryptoJS.enc.Utf8);
let decrypted = CryptoJS.enc.Base64.parse(decryptedB64).toString(CryptoJS.enc.Utf8); // Base64 decode the decrypted data
return decrypted;
}
var ciphertext = "rFWejB1Pj6W3Gh1bheFqDZPMO9POKbhGPOP6eAH9BSk=";
var key = "7f7720b911c2ecbb22637ed7adef41e82d44b6a0";
console.log(decryptData(ciphertext, key));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
Please note that a static IV is insecure (but maybe you are only using a static IV for testing purposes).
Upvotes: 2