【问题标题】:File Decryption not working in Node when encrypted from php从 php 加密时,文件解密在 Node 中不起作用
【发布时间】:2017-07-27 09:53:51
【问题描述】:

终于解决了,你可以在下面看到我的答案 从 php 加密时,文件解密在 Node 中不起作用 PHP 代码加密

<?php

$key = "f9036c20bdb656106fd176d260878c63";
$iv = "7152201381f54b46";




exec('openssl enc -aes-256-cbc   -K '.$key.' -iv '.$iv.' -in a.txt -out b.txt');



exec('openssl enc -d -aes-256-cbc  -K '.$key.' -iv '.$iv.' -in b.txt -out outr.txt');
?>

在 PHP 中解密工作正常

以下两种方法的解密JS代码都不起作用

var CryptoJS = require('crypto-js');
var key ="f9036c20bdb656106fd176d260878c63";

var iv1 = "7152201381f54b46";


var text = require('fs').readFileSync('../b.txt');

var bytes  = CryptoJS.AES.decrypt(text,key,{iv:iv1, mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7 });

console.log(CryptoJS.enc.Utf8.stringify(bytes));
require('fs').writeFile('../out.txt', CryptoJS.enc.Utf8.stringify(bytes), function (err) {
        if (err) {
            return console.error(err);
        }
    });

也尝试过加密没有运气

    const crypto = require('crypto');
const fs = require('fs');

var secret = "f9036c20bdb656106fd176d260878c63";
const buf_secret = Buffer.from(secret);

var iv = "7152201381f54b46";
const buf_iv = Buffer.from(iv);


const decipher = crypto.createCipheriv('aes-256-cbc', buf_secret, buf_iv);
decipher.setAutoPadding(true);
fs.readFile('../b.txt', function (err, data) {
    if (err) {
        return console.log(err);
    }
    const buf_data = Buffer.from(data);
    console.log(buf_data);
    let decrypted = decipher.update(buf_data, 'utf8');
    decrypted += decipher.final('utf8');
    console.log(decrypted);

});

我确定存在一些填充问题,有人可以指出它有什么错误吗?

【问题讨论】:

  • 您的密钥只有 128 位,而您的 IV 是 64,两者都是错误的。 openssl enc -K -iv 用零填充;我不知道这两个 JS 是做什么的。同样在第二个中,您似乎声称您的密文不是base64,尽管我希望这会引发一些错误,并且没有填充加密,这将导致您的输出包含添加的垃圾根据您的外观,可能不可见。
  • @dave_thompson_085 我把它修好了,问题是 PHP openssl 接受密钥和 iv 作为十六进制。对于 openssl256 密钥长度应为 64,iv 长度应为 32,但在 PHP 中,密钥长度为 32,iv 长度为 16,用于 openssl128,因此 PHP 添加尾随零。在 JS 中添加尾随零并将其视为十六进制后其工作正常。
  • 准确来说PHP只是将(十六进制)字符串传递给openssl;是 openssl 从十六进制转换,发现它们太短和垫。但结果相同。

标签: encryption openssl cryptography aes cryptojs


【解决方案1】:

解决了。问题是 PHP openssl 接受 key 和 iv 作为十六进制。对于 openssl256,密钥长度应为 64,iv 长度应为 32,但在 PHP 中,密钥长度为 32,iv 长度为 16,用于 openssl128,因此 PHP 添加了尾随零。在 JS 中添加尾随零并将其视为十六进制后,它的工作正常。

const crypto = require('crypto');
const fs = require('fs');
const key_size = 64;
const iv_size = 32;

var secret = "f9036c20bdb656106fd176d260878c63";
secret = pad(secret,key_size,"0"); //pad with trailing zeros

const buf_secret = Buffer.from(secret,'hex');

var iv = "7152201381f54b46";
iv = pad(iv,iv_size,"0");//pad with trailing zeros

const buf_iv = Buffer.from(iv,'hex');



const decipher = crypto.createDecipheriv('aes-256-cbc', buf_secret, buf_iv);
decipher.setAutoPadding(true);

const input = fs.createReadStream('../b.txt');
const output = fs.createWriteStream('../decrypted.txt');

input.pipe(decipher).pipe(output);

//content if you want instead of direct writing
//fs.readFile('../b.txt', function (err, data) {
//    if (err) {
//        return console.log(err);
//    }
//    const buf_data = Buffer.from(data);
//    console.log(buf_data);
//    let decrypted = decipher.update(buf_data, 'utf8');
//    decrypted += decipher.final('utf8');
//    console.log(decrypted);
//
//});

//for padding trailing zeros
function pad(value, width, padchar) {

    while (value.length < width) {
        value += padchar;
    }
    return value;
}

【讨论】:

    猜你喜欢
    • 2015-07-19
    • 1970-01-01
    • 2019-03-04
    • 2021-03-25
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    相关资源
    最近更新 更多