Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用加密模块对NodeJS进行PHP-AES加密_Javascript_Php_Node.js_Encryption_Node Crypto - Fatal编程技术网

Javascript 使用加密模块对NodeJS进行PHP-AES加密

Javascript 使用加密模块对NodeJS进行PHP-AES加密,javascript,php,node.js,encryption,node-crypto,Javascript,Php,Node.js,Encryption,Node Crypto,我的任务是遵循给定的、有效的PHP加密到node.js中。使用任何节点模块包。我不需要做解密,因为它已经存在于他们的API中,我只需要将加密的值传递给他们的API进行解密,这是在PHP中。我尝试使用节点加密和分离md5模块。以下是伪代码: 数据加密算法 创建一个16字节的随机salt和hash。每次你打电话时,盐都是新创建的 API 散列提供的加密密钥 使用“AES-128-CBC”进行加密,并将散列的salt值用作向量和散列 加密密钥 为salt添加前缀并附加加密数据 执行Base64编码

我的任务是遵循给定的、有效的PHP加密到node.js中。使用任何节点模块包。我不需要做解密,因为它已经存在于他们的API中,我只需要将加密的值传递给他们的API进行解密,这是在PHP中。我尝试使用节点加密和分离md5模块。以下是伪代码:

  • 数据加密算法
  • 创建一个16字节的随机salt和hash。每次你打电话时,盐都是新创建的 API
  • 散列提供的加密密钥
  • 使用“AES-128-CBC”进行加密,并将散列的salt值用作向量和散列 加密密钥
  • 为salt添加前缀并附加加密数据
  • 执行Base64编码
  • JSON编码和post请求
我想我几乎完成了几个步骤来获得成功的响应这里是我当前的node.js代码

节点:

以下是可用的php代码:

$data = json_encode([
  'username' => "jCpVyf3VEt",
  'password' => "eGD6TWKmnn",
  'account_no' => "0030300155398",
  'tran_date' => "08/06/2019 10:30:45",
  'reference_no' => "12328ALHYGZC20",
  'area' => "JENRA DAU"]);

function encrypt( $data) {
  $key = md5("IfZDGbVDHTxlJIkK", true);
  $cipher = "aes-128-cbc";
  $salt = openssl_random_pseudo_bytes(16);
  $iv = md5( $salt, true);
  $encrypted_bin =  $salt . openssl_encrypt( serialize( $data ), $cipher, $key, true, $iv);
  $encrypted_str = base64_encode( $encrypted_bin);

  return $encrypted_str;

}

echo encrypt($data);
出于测试目的,以下是API中用于解密的PHP代码:

$data = 'LI5BJJw1PEhWellnjKEt3g9oaHs8uDDknBT2qDNI7Rfs644+IjobOaFxlrIrOvDm7dkASRsOTu4Yuxzi4I5q29QoE5huH6y4/XZXsResZjLPidv1ToTnhB2UKXH5rX/g/8Od7ljO6VLVAS7zx+94xeOgtpP/idkkpDi1fRNGvnOkl1c6fcyVhwl2Pv+ijKSK9+ou+54dfQrCng2uBzKC6RrHY3lvP7ktsSvtnkXFqksrpjfJ2gnMH6sMIMzru1+D';

function decrypt($encrypted) {
 $cipher = "aes-128-cbc";
 $key = md5("IfZDGbVDHTxlJIkK", true);
    $data = base64_decode($encrypted);
    $salt = substr($data, 0, 16);
    $iv = md5($salt, true);
    $decrypted_bin = openssl_decrypt(substr($data, 16, strlen($data)), $cipher, $key, true, $iv);

    if($decrypted_bin === false) {
    return json_encode([ -102 => "Authentication Failed"]);
    }

    return unserialize( $decrypted_bin);
}
echo decrypt($data);

运行PHP加密代码会导致来自PHP解密的成功响应。但是当我运行Node.js加密时,我能够获得加密数据,但是当我测试Node.js中的加密数据并将加密值发送到PHP解密代码时,结果是身份验证错误。似乎我无法将PHP加密算法转换为节点
.js这是一个非常有趣的例子。。我认为主要的问题是在Node.js中连接salt和加密数据的方法

我发现下面的代码工作得很好,它给出了与PHP代码相同的结果

注意,我在这里使用的是一个固定的salt(从固定的base64字符串解码),因为这给了我们一个确定性的输出。您可能应该切换到在生产中使用crypto.randomBytes

此外,PHP在json输出中将“/”编码为“\/”,请参阅。这当然可以在PHP中配置(在JSON_encode中使用标志JSON_UNESCAPED_SLASHES),但我怀疑在您的情况下无法更改。这就是为什么我在json明文中将“/”替换为“\/”

const reqBody = {
    "username": "jCpVyf3VEt",
    "password": "eGD6TWKmnn",
    "account_no": "0030300155398",
    "tran_date": "08/06/2019 10:30:45",
    "reference_no": "12328ALHYGZC20",
    "area": "JENRA DAU"
};
const Serialize = require('php-serialize')
const md5 = require('md5');
//encrypt
const crypto = require('crypto'),
algorithm = 'aes-128-cbc',
key = 'IfZDGbVDHTxlJIkK',
inputEncoding = 'utf8',
outputEncoding = 'base64';

function encrypt(input, key, salt) {
    let serialized = Serialize.serialize(input);
    let iv = md5(salt);
    let hKey = md5(key);

    let cipher = crypto.createCipheriv(algorithm, Buffer.from(hKey, 'hex'), Buffer.from(iv, 'hex'));
    let crypted = cipher.update(serialized, inputEncoding);
    let encrypted = Buffer.concat([salt, crypted, cipher.final()]);
    return encrypted.toString(outputEncoding);
}

// We must escape forward slashes here, since this is how PHP will behave. 
let data = JSON.stringify(reqBody).replace(/\//ig, "\\/");

// We can use any random salt here, e.g. crypto.randomBytes For this example we'll use the same as the existing encrypted data. 
let salt = Buffer.from('LI5BJJw1PEhWellnjKEt3g==', 'base64');
console.log("Encrypted data: ", encrypt(data, key, salt));

谢谢terry,即使是随机生成的salt 16字节,它现在也可以工作了。我想知道为什么你这么容易就解决了我的问题?为此工作了不少于8小时。试错这不容易:-)这是一个难题。我刚刚比较了PHP和Node.js之间的各种中间阶段,我以前也处理过类似的问题!好吧我现在可以睡个好觉了,我有信心明天能赶上最后期限!非常感谢你的尊重!
const reqBody = {
    "username": "jCpVyf3VEt",
    "password": "eGD6TWKmnn",
    "account_no": "0030300155398",
    "tran_date": "08/06/2019 10:30:45",
    "reference_no": "12328ALHYGZC20",
    "area": "JENRA DAU"
};
const Serialize = require('php-serialize')
const md5 = require('md5');
//encrypt
const crypto = require('crypto'),
algorithm = 'aes-128-cbc',
key = 'IfZDGbVDHTxlJIkK',
inputEncoding = 'utf8',
outputEncoding = 'base64';

function encrypt(input, key, salt) {
    let serialized = Serialize.serialize(input);
    let iv = md5(salt);
    let hKey = md5(key);

    let cipher = crypto.createCipheriv(algorithm, Buffer.from(hKey, 'hex'), Buffer.from(iv, 'hex'));
    let crypted = cipher.update(serialized, inputEncoding);
    let encrypted = Buffer.concat([salt, crypted, cipher.final()]);
    return encrypted.toString(outputEncoding);
}

// We must escape forward slashes here, since this is how PHP will behave. 
let data = JSON.stringify(reqBody).replace(/\//ig, "\\/");

// We can use any random salt here, e.g. crypto.randomBytes For this example we'll use the same as the existing encrypted data. 
let salt = Buffer.from('LI5BJJw1PEhWellnjKEt3g==', 'base64');
console.log("Encrypted data: ", encrypt(data, key, salt));