AES Encryption In JS, Decrypt In PHP?

- 1 answer

When my form gets submitted, it will first make a request to this controller action to get the server's public key:

public function preprocessPayment(Request $request) {
    // Get public key
    $publicKey = $this->EncryptionService->getPublicKey();

    // Generate iv
    $method = 'aes-256-cbc';
    $ivlen = openssl_cipher_iv_length($method);
    $iv = openssl_random_pseudo_bytes($ivlen);

    return response()->json([
        'success' => true, 
        'data' => [
            'public_key' => $publicKey,
            'iv' => $iv

After that, in my client, I'm going to generate a secret key using AES via CryptoJS, that will later be encrypted with the public_key.

Then, the form data will be encrypted in AES using the AES secret key, and then the following payload will be submitted to the server:

    secret_key: xxx,
    iv: xxx,
    form_data: {...}

The AES encrypted data will be processed here:

public function storePayment(Request $request) {
    // Decrypt AES secret key (that was encrypted with the RSA public key),
        // using RSA private key
    // Decrypt AES client data with secret key
    // Store data in database

My question is, how will I do the AES secret key generation and encryption on the client side using CryptoJS? Could not seem to find any good documentation about it. How should I format the data so it will be accepted by the server for decryption?

And I'm stuck with decrypting AES in PHP, because it requires a $tag and I don't know where to get that when everything is coming from the client.

$originalData = openssl_decrypt($data, 'aes-128-gcm', $secretKey, $options=0, $iv, $tag);

I found this link:, but I'm not sure how to make it work because I'm not sure where to locate the needed scripts.


I made a mistake, for decrypting on the server, I was using aes-128-gcm instead of aes-256-cbc. When I corrected it, I was able to decrypt without the $tag.



An AES-256 key is nothing more than 32 random bytes. So you create the key by using a cryptographically secure random number generator.

However, both RSA PKCS#1 v1.5 and AES-CBC are vulnerable to padding oracle attacks. So not only can an adversary change the message, the message is also not kept confidential. In other words, you can use 256 bit keys as much as you want, but you should not create your own transport protocol, because the perceived security just isn't there.

You could sign the ciphertext, but that has problems as well - generally we sign then encrypt.

Use TLS.