Javascript 在JS上加密,在PHP中解密?

Javascript 在JS上加密,在PHP中解密?,javascript,php,angularjs,encryption,cryptojs,Javascript,Php,Angularjs,Encryption,Cryptojs,我现在被困在这里,这是客户端的: $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.Word

我现在被困在这里,这是客户端的:

$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 decryptData($data) 
{
    $privateKey = $this->getPrivateKey();

    if (empty($privateKey)) {
        $this->regenerateKeypair();
    }

    $privateKey = $this->getPrivateKey();
    $binaryData = hex2bin($data);
    openssl_private_decrypt($binaryData, $decrypted, $privateKey);

    return $decrypted;
}
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;
    }
}
这是我在服务器中的控制器功能:

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
}
从my
EncryptionService

对于RSA解密:

{
    iv: "ae3bafa370bdc0c8a6b47ab1b792ec58"
    payment: "e12f9db635984ec2f146bd34e433ef912580c4b3c7c1efe0a8e3fa6981abefa860630752539a9af88a9db0c198a63b804855d4b56357f75456785d7313908c6e"
    secret_key: "emMKQ2QOWtzQAHhur4FLQCyBSK9zzPzomjWyDbeOM3VpjIKb1aNs9SL4P1nhuizEwuM2os/FXsN6MJz/cwxQWakK3tnVFvmt..."
}
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;
}
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;
    }
}
对于AES解密:

{
    iv: "ae3bafa370bdc0c8a6b47ab1b792ec58"
    payment: "e12f9db635984ec2f146bd34e433ef912580c4b3c7c1efe0a8e3fa6981abefa860630752539a9af88a9db0c198a63b804855d4b56357f75456785d7313908c6e"
    secret_key: "emMKQ2QOWtzQAHhur4FLQCyBSK9zzPzomjWyDbeOM3VpjIKb1aNs9SL4P1nhuizEwuM2os/FXsN6MJz/cwxQWakK3tnVFvmt..."
}
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;
}
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()中的这一行:

如何正确地从客户端发送数据,以便服务器能够正确地解密数据

编辑:

我正在使用这些库:


您从JavaScript获取的
$secretKey
数据似乎是base64编码的,而不是十六进制的。PHP端的这一更改可能会起作用(但仅适用于
$secretKey
):


$binaryData=base64\u解码($data)

您从JavaScript中获取的
$secretKey
数据似乎是base64编码的,而不是十六进制的。PHP端的这一更改可能会起作用(但仅适用于
$secretKey
):


$binaryData=base64\u解码($data)

Hmm,解决了错误,但是数据没有被解密,我无法获得原始值。我想我仍然缺少一些东西。你得到了什么而不是原始值?什么都没有,或者什么东西弄坏了?当尝试使用
decryptSecretData()
解密支付数据时,我只得到一个
false
。试图通过
decryptData()
解密密钥时给了我一个空字符串。嗯,这解决了错误,但是数据没有被解密,我无法获得原始值。我想我仍然缺少一些东西。你得到了什么而不是原始值?什么都没有,或者什么东西弄坏了?当尝试使用
decryptSecretData()
解密支付数据时,我只得到一个
false
。试图通过
decryptData()
解密密钥时给了我一个空字符串。到达服务器的数据是否完好无损?POST请求使用什么
内容类型
?@georgeawg对于
内容类型
,值为
text/html;字符集=UTF-8
。数据似乎完好无损。我很惊讶这篇文章是
text/html
。AngularJS框架通常使用
application/json
。代码中的术语也令人困惑。有一个名为
secret\u key
的变量,但发送对象的
secret\u key
属性不同。这使得代码难以理解、调试、测试和维护。@georgeawg很抱歉造成这种混乱,您是指这一部分吗<代码>$scope.payment\u data.secret\u key=secret\u key\u rsa
AES密钥必须使用来自服务器的公钥在RSA中进行加密,以便只有服务器可以使用其私钥对其进行解密。(客户端的RSA加密部分已经包含在问题中,我已经对该部分进行了注释。)到达服务器的数据是否完好无损?POST请求使用什么
内容类型
?@georgeawg对于
内容类型
,值为
text/html;字符集=UTF-8
。数据似乎完好无损。我很惊讶这篇文章是
text/html
。AngularJS框架通常使用
application/json
。代码中的术语也令人困惑。有一个名为
secret\u key
的变量,但发送对象的
secret\u key
属性不同。这使得代码难以理解、调试、测试和维护。@georgeawg很抱歉造成这种混乱,您是指这一部分吗<代码>$scope.payment\u data.secret\u key=secret\u key\u rsa
AES密钥必须使用来自服务器的公钥在RSA中进行加密,以便只有服务器可以使用其私钥对其进行解密。(客户端的RSA加密部分已经包含在问题中,我已经对该部分进行了评论。)