首页 > 解决方案 > AES encryption in JS, decrypt in PHP?

问题描述

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: http://cryptojs.altervista.org/js-php/, but I'm not sure how to make it work because I'm not sure where to locate the needed scripts.

Edit:

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.

标签: javascriptphplaravelencryption

解决方案


一个 AES-256 密钥不过是 32 个随机字节。因此,您可以使用加密安全的随机数生成器来创建密钥。

但是,RSA PKCS#1 v1.5 和 AES-CBC 都容易受到填充预言攻击。因此,对手不仅可以更改消息,而且消息也不会保密。换句话说,您可以根据需要尽可能多地使用 256 位密钥,但您不应该创建自己的传输协议,因为感知到的安全性不存在。

您可以对密文进行签名,但这也有问题——通常我们先签名然后加密。

使用 TLS。


推荐阅读