javascript - 在 JS 上加密,在 PHP 中解密?
问题描述
我现在被困在这里,这是来自客户端:
$scope.encryptFormData = function() {
// Get payment data
var paymentData = JSON.stringify($scope.payment);
// Generate AES secret key
var secret_key = $scope.generateKey(paymentData);
var iv = CryptoJS.lib.WordArray.random(16);
// Encrypt form data using AES secret key
var cipherPaymentData = CryptoJS.AES.encrypt(paymentData, secret_key, {iv: iv});
// Encrypt AES secret key with RSA public key from server
var secret_key_rsa = null;
var encrypt = new JSEncrypt();
encrypt.setPublicKey($scope.public_key);
secret_key_rsa = encrypt.encrypt(secret_key);
// Assign values to form object
var iv_hex = CryptoJS.enc.Hex.stringify(iv);
var payment_data_hex = CryptoJS.enc.Hex.stringify(cipherPaymentData.ciphertext);
$scope.payment_data.secret_key = secret_key_rsa;
$scope.payment_data.iv = iv_hex;
$scope.payment_data.payment = payment_data_hex;
// Send form data to server
};
$scope.generateKey = function(p) {
var salt = CryptoJS.lib.WordArray.random(128/8);
return CryptoJS.PBKDF2(p, salt, { keySize: 512/32, iterations: 1000 });
}
现在,我将此有效负载发送到服务器进行解密:
{
iv: "ae3bafa370bdc0c8a6b47ab1b792ec58"
payment: "e12f9db635984ec2f146bd34e433ef912580c4b3c7c1efe0a8e3fa6981abefa860630752539a9af88a9db0c198a63b804855d4b56357f75456785d7313908c6e"
secret_key: "emMKQ2QOWtzQAHhur4FLQCyBSK9zzPzomjWyDbeOM3VpjIKb1aNs9SL4P1nhuizEwuM2os/FXsN6MJz/cwxQWakK3tnVFvmt..."
}
这是我在服务器中的控制器功能:
public function storePayment(Request $request) {
$postData = $request->data;
// Decrypt AES secret key, using private key
$iv = $postData['iv'];
$secretKey = $this->EncryptionService->decryptData($postData['secret_key']);
// Decrypt AES client form data with secret key
$paymentData = $this->EncryptionService->decryptSecretData($postData['payment'], $secretKey, $iv);
// Print decrypted data
}
从我的EncryptionService
:
对于 RSA 解密:
public function decryptData($data)
{
$privateKey = $this->getPrivateKey();
if (empty($privateKey)) {
$this->regenerateKeypair();
}
$privateKey = $this->getPrivateKey();
$binaryData = hex2bin($data);
openssl_private_decrypt($binaryData, $decrypted, $privateKey);
return $decrypted;
}
对于 AES 解密:
public function decryptSecretData($data, $secretKey, $iv)
{
$cipher = "aes-256-cbc";
if (in_array($cipher, openssl_get_cipher_methods()))
{
$iv = hex2bin($iv);
$originalData = openssl_decrypt($data, $cipher, $secretKey, $options=0, $iv);
return $originalData;
}
}
但现在我只是收到这个错误:
file: "...\Services\EncryptionService.php"
line: 101
message: "hex2bin(): Input string must be hexadecimal string"
它指向里面的这条线decryptData()
:
$binaryData = hex2bin($data);
如何正确地从客户端发送数据,以便服务器可以正确解密它?
编辑:
我正在使用这些库:
https://github.com/travist/jsencrypt
https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js
解决方案
看起来您从 JavaScript 获取的数据$secretKey
是 base64 编码的,而不是十六进制的。也许 PHP 方面的这种更改会起作用(但仅适用于$secretKey
):
$binaryData = base64_decode($data);
推荐阅读
- c - C 声明符理解
- angular - 库的角度示意图:构建示意图在角度 10 中产生错误
- java - 无法使用 Spring 4.1.1 和 camel 2.14.0 上传多个图像
- vue.js - Vue component loses input when asynchronous call updates another property
- c# - Xamarin Android Google SSO CustomUrlSchemeInterceptorActivity
- javascript - 如何使滑块使用十进制值
- python - 试图抓取图像,我得到空输出
- firebase - 从 Firebase 中提取 FCM 服务器密钥
- javascript - $error 将 POST 发送到 index.php 中的 div
- c# - FrameworkElement.BringToFront() 和 SendToBack() 实现