PHP 上的 3DES 加密产生与 NodeJS 不同的结果
3DES crypto on PHP produces different result from NodeJS
我正在构建一个需要信用卡 3DES-CBC 加密的结帐,但我在 PHP 和 NodeJS 上得到不同的结果。
PHP代码:
<?php
$postfields = array(
'CartaoNumero' => '0000000000000000',
'CartaoMesAno' => '00/0000',
'CartaoSeg' => '000',
'CartaoNome' => 'Name Lastname',
'IdentFatura' => 'companyName',
'Valor' => '100',
'NomeCliente' => 'Name Lastname',
'EmailCliente' => 'test@testcompany.com',
'CpfCliente' => preg_replace("/[.-]/", "", '111.222.333-44'),
);
$criptoKey = 'yzzqaKsC5iaZV0a2\/oexiimfYhh1yd39';
$criptoKey = base64_decode($criptoKey);
$criptoKey = unpack('H*', $criptoKey);
$criptoKey = implode($criptoKey);
$criptoIV = 'pO432mbTiCI=';
$criptoIV = base64_decode($criptoIV);
$criptoIV = unpack('H*', $criptoIV);
$criptoIV = implode($criptoIV);
$dataOfCard = json_encode($postfields);
$dataOfCard = openssl_encrypt($dataOfCard, 'DES-EDE3-CBC', $criptoKey, 0, $criptoIV);
echo $dataOfCard;
?>
Result: bxanrc856Z+7EoICArPYFvAjFfQfmIPXyUzKjEenlMQ4QPfWbfQELs8Z3i2jWq3mn2hFZUs6PCnno2cejkY2Jtaw94Bs5E7JN4kzyn2lMH+l8LwSHdOAytw4KsxEM7MssZlcmLqk+ZaBYehZM26Ci5JcX6oBcARDxPs9EMWYzttS/xDEu2gQzaExqLZlAC9+XwWZwpVPJfgzcS5YA1PRcliYyG01G8Uj9SAFcPtJOPUttkLrrcSSuHo3SsnnhjeRyiEmR0FhgvHlnx3UCAxo4fhtH2Z6z5E5nV2RHzYU81FIP5S1Jikh4xyZAZ3Xtgm8enWl3wTg/6o=
NodeJS 代码:
var dataOfCard ={'CartaoNumero':'0000000000000000','CartaoMesAno':'00/0000','CartaoSeg':'000','CartaoNome':'Name Lastname','IdentFatura':'companyName','Valor':'100','NomeCliente':'Name Lastname','EmailCliente':'test@testcompany.com','CpfCliente':'11122233344'};
var secretKey = 'yzzqaKsC5iaZV0a2\/oexiimfYhh1yd39';
var secretIV = 'pO432mbTiCI=';
global.crypto = require('crypto')
async function encryptCardData(dataOfCard, secretKey, secretIV) {
try {
const des3_key = new Buffer.from(secretKey, "base64");
const des3_iv = new Buffer.from(secretIV, "base64");
const cardString = JSON.stringify(dataOfCard);
const cipher = crypto.createCipheriv('des-ede3-cbc', des3_key, des3_iv);
const encrypted = cipher.update(cardString, 'utf8', 'base64');
return encrypted + cipher.final('base64');
} catch (error) {
console.error("Falha no momento de encrypt dos dados do cartão.", error.message);
throw error;
}
}
Result: TFMIANgM+pd7UOhakdfbcC2ulKLL0X6F6sXAyK3CvsnGi0f64n/sGOACQHM/rNqr/EA/QlFsTQFRBYxf6EKNg6g3Empx0FFZY77qv7oMJO3w++TW14uOaVk72uz0U9uHF2YHZGOnJ2Lm8yGang3XuT6smPraV4uw/Arzaw/qSA56ao7fQUeFhGRvIy19ta8QfMMirCRyJrnFCvK4Xmc+FxUH6qxN/svYZcz+jziPVtHryWNad9d1hO5AkgwClNI7yDaA5PxgIUQ3G+jGl1GfhI8i6Xfn1VYgfjNqW48fuoSpAz7ShNX6S1k/nyeNpF9vPZNpMEydQ94=
NodeJS 正在生成正确的结果。我需要在 PHP 模型上更正什么?
您有 2 个问题。
- 您无缘无故地在键和 iv 上调用
unpack()
和 implode()
。不要那样做。
- 你的明文不一样。 PHP 的
json_encode()
默认值包括转义斜杠,因此 "00/0000"
变为 "00\/0000"
。您可以使用 JSON_UNESCAPED_SLASHES
标志禁用此功能。
我正在构建一个需要信用卡 3DES-CBC 加密的结帐,但我在 PHP 和 NodeJS 上得到不同的结果。
PHP代码:
<?php
$postfields = array(
'CartaoNumero' => '0000000000000000',
'CartaoMesAno' => '00/0000',
'CartaoSeg' => '000',
'CartaoNome' => 'Name Lastname',
'IdentFatura' => 'companyName',
'Valor' => '100',
'NomeCliente' => 'Name Lastname',
'EmailCliente' => 'test@testcompany.com',
'CpfCliente' => preg_replace("/[.-]/", "", '111.222.333-44'),
);
$criptoKey = 'yzzqaKsC5iaZV0a2\/oexiimfYhh1yd39';
$criptoKey = base64_decode($criptoKey);
$criptoKey = unpack('H*', $criptoKey);
$criptoKey = implode($criptoKey);
$criptoIV = 'pO432mbTiCI=';
$criptoIV = base64_decode($criptoIV);
$criptoIV = unpack('H*', $criptoIV);
$criptoIV = implode($criptoIV);
$dataOfCard = json_encode($postfields);
$dataOfCard = openssl_encrypt($dataOfCard, 'DES-EDE3-CBC', $criptoKey, 0, $criptoIV);
echo $dataOfCard;
?>
Result: bxanrc856Z+7EoICArPYFvAjFfQfmIPXyUzKjEenlMQ4QPfWbfQELs8Z3i2jWq3mn2hFZUs6PCnno2cejkY2Jtaw94Bs5E7JN4kzyn2lMH+l8LwSHdOAytw4KsxEM7MssZlcmLqk+ZaBYehZM26Ci5JcX6oBcARDxPs9EMWYzttS/xDEu2gQzaExqLZlAC9+XwWZwpVPJfgzcS5YA1PRcliYyG01G8Uj9SAFcPtJOPUttkLrrcSSuHo3SsnnhjeRyiEmR0FhgvHlnx3UCAxo4fhtH2Z6z5E5nV2RHzYU81FIP5S1Jikh4xyZAZ3Xtgm8enWl3wTg/6o=
NodeJS 代码:
var dataOfCard ={'CartaoNumero':'0000000000000000','CartaoMesAno':'00/0000','CartaoSeg':'000','CartaoNome':'Name Lastname','IdentFatura':'companyName','Valor':'100','NomeCliente':'Name Lastname','EmailCliente':'test@testcompany.com','CpfCliente':'11122233344'};
var secretKey = 'yzzqaKsC5iaZV0a2\/oexiimfYhh1yd39';
var secretIV = 'pO432mbTiCI=';
global.crypto = require('crypto')
async function encryptCardData(dataOfCard, secretKey, secretIV) {
try {
const des3_key = new Buffer.from(secretKey, "base64");
const des3_iv = new Buffer.from(secretIV, "base64");
const cardString = JSON.stringify(dataOfCard);
const cipher = crypto.createCipheriv('des-ede3-cbc', des3_key, des3_iv);
const encrypted = cipher.update(cardString, 'utf8', 'base64');
return encrypted + cipher.final('base64');
} catch (error) {
console.error("Falha no momento de encrypt dos dados do cartão.", error.message);
throw error;
}
}
Result: TFMIANgM+pd7UOhakdfbcC2ulKLL0X6F6sXAyK3CvsnGi0f64n/sGOACQHM/rNqr/EA/QlFsTQFRBYxf6EKNg6g3Empx0FFZY77qv7oMJO3w++TW14uOaVk72uz0U9uHF2YHZGOnJ2Lm8yGang3XuT6smPraV4uw/Arzaw/qSA56ao7fQUeFhGRvIy19ta8QfMMirCRyJrnFCvK4Xmc+FxUH6qxN/svYZcz+jziPVtHryWNad9d1hO5AkgwClNI7yDaA5PxgIUQ3G+jGl1GfhI8i6Xfn1VYgfjNqW48fuoSpAz7ShNX6S1k/nyeNpF9vPZNpMEydQ94=
NodeJS 正在生成正确的结果。我需要在 PHP 模型上更正什么?
您有 2 个问题。
- 您无缘无故地在键和 iv 上调用
unpack()
和implode()
。不要那样做。 - 你的明文不一样。 PHP 的
json_encode()
默认值包括转义斜杠,因此"00/0000"
变为"00\/0000"
。您可以使用JSON_UNESCAPED_SLASHES
标志禁用此功能。