javascript - 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
.
解决方案
一个 AES-256 密钥不过是 32 个随机字节。因此,您可以使用加密安全的随机数生成器来创建密钥。
但是,RSA PKCS#1 v1.5 和 AES-CBC 都容易受到填充预言攻击。因此,对手不仅可以更改消息,而且消息也不会保密。换句话说,您可以根据需要尽可能多地使用 256 位密钥,但您不应该创建自己的传输协议,因为感知到的安全性不存在。
您可以对密文进行签名,但这也有问题——通常我们先签名然后加密。
使用 TLS。
推荐阅读
- python - (再次)在 Windows 上访问 Python 中的长路径
- javascript - 如何在地图中为我的密钥道具生成唯一密钥?反应
- laravel - Laravel,自动生成新链接
- rust - 我可以运行夜间和稳定的编译器吗?
- firebase - 如何阻止从控制台更改 Firebase 实时数据库
- sharepoint - 以“归档格式”从 OneNote 文档中提取文本
- c++ - 无效指针的条件
- python - 如何从索引中的时间戳获取一天的秒数?
- javascript - 如何将 MongoDB ObjectID 作为十六进制字符串获取到渲染器中
- javascript - formControl 的值未显示在视图中