I want to encrypt something in PHP and decrypt it in JavaScript.
My problem is that I’m getting an “Error decrypting: OperationError” when trying to decrypt in JS, but no more hints what might be wrong.
I broke it down to a testfile like this, perhaps someone got an idea what the problem might be?
<?php
$sKey = "RscFrKLJaAdEFF5Kcp1ShY5xsTu3AKisdaxIggioiks="; // already base64_encoded
$cipher = "AES-256-CBC";
$ivlen = openssl_cipher_iv_length($cipher); // 16 Bytes
$iv = openssl_random_pseudo_bytes($ivlen);
$sPlainTxt = "My encrypted text";
$sEncoded = openssl_encrypt($sPlainTxt, $cipher, $sKey, OPENSSL_RAW_DATA, $iv);
// Just to test if it's possible to decrypt again in PHP
$sDecodedTxt = openssl_decrypt($sEncoded, $cipher, $sKey, OPENSSL_RAW_DATA, $iv); // This works
?>
<script>
$(document).ready(function() {
var encryptedString = "<?php print base64_encode($iv.$sEncoded); ?>";
decryptString(encryptedString, '<?php print $sKey;?>').then(result=> {
if (result!== null)
{ // Show result
console.log(result);
}
}).catch(error => {
console.log("Error");
});
});
async function decryptString(encryptedString, key) {
const keyBytes = Uint8Array.from(atob(key), c => c.charCodeAt(0)); // Base64
const keyBuffer = keyBytes.buffer;
const keyMaterial = await window.crypto.subtle.importKey(
"raw",
keyBuffer,
{ name: "AES-CBC" },
false,
["decrypt"]
);
const encryptedData = Uint8Array.from(atob(encryptedString), c => c.charCodeAt(0)); // Base64
// extract IV and Ciphertext
const iv = encryptedData.slice(0, 16); // First 16 bytes contain iv
const ciphertext = encryptedData.slice(16); // the rest is ciphertext
try {
const decrypted = await window.crypto.subtle.decrypt(
{ name: "AES-CBC", iv },
keyMaterial,
ciphertext
);
return new TextDecoder().decode(decrypted);
} catch (e) {
console.error("Error decrypting:", e);
return null;
}
}
</script>
P.S.: I know this is no “high security”-operation, it’s more to obfuscate some things from spam-bots. Might be that AES is a bit “big” for that, but it seems to be there so I thought I might even use it.