JuneAndGreen / sm-crypto

国密算法js版
MIT License
954 stars 254 forks source link

sm4加密文件后无法解密 #93

Closed GuoHuaijian closed 1 year ago

GuoHuaijian commented 1 year ago

// 文件加密 function encryptFile(inputPath, outputPath, key) { const input = fs.readFileSync(inputPath); const encryptedData = sm4.encrypt(input, key, { mode: 'ecb', padding: 'pkcs#7' }); fs.writeFileSync(outputPath, encryptedData, 'hex'); }

// 文件解密 function decryptFile(inputPath, outputPath, key) { const encryptedData = fs.readFileSync(inputPath, 'hex'); const decryptedData = sm4.decrypt(encryptedData, key, { mode: 'ecb', padding: 'pkcs#7' }); fs.writeFileSync(outputPath, decryptedData, 'utf8'); }

Blank0120 commented 1 year ago

我用你的代码跑目前完全可以

const sm4 = require('sm-crypto').sm4;
const fs = require('fs');

// 文件加密
function encryptFile(inputPath, outputPath, key) {
    const input = fs.readFileSync(inputPath);
    const encryptedData = sm4.encrypt(input, key, { mode: 'ecb', padding: 'pkcs#7' });
    fs.writeFileSync(outputPath, encryptedData, 'hex');
}

// 文件解密
function decryptFile(inputPath, outputPath, key) {
    const encryptedData = fs.readFileSync(inputPath, 'hex');
    const decryptedData = sm4.decrypt(encryptedData, key, { mode: 'ecb', padding: 'pkcs#7' });
    fs.writeFileSync(outputPath, decryptedData, 'utf8');
}

encryptFile('./test-sm-crypto.txt', './test-sm-crypto-encrypted.txt', '11223344556677881122334455667788');

decryptFile('./test-sm-crypto-encrypted.txt', './test-sm-crypto-decrypted.txt', '11223344556677881122334455667788');
GuoHuaijian commented 1 year ago

txt文件是可以的 其他格式不行 @Blank0120

Blank0120 commented 1 year ago

txt文件是可以的 其他格式不行 @Blank0120

你说的对,png, jpg解密会遇到非char的值超过unicode码表了,导致报错。

changhr2013 commented 1 year ago

二进制文件需要读取/写入字节数组,本身库是支持传入字节数组的:

import SmCrypto from "sm-crypto";
import fs from "fs";

const{sm4}= SmCrypto;

const filePath = '/Downloads/20221118160713.png';
const outputFilePath = '/Downloads/20221118160713-enc';
const decFilePath = '/Downloads/20221118160713-dec.png';
let key = "f4320510c51fda88e6d1cc94b72bb2b8";

encryptFile(filePath, outputFilePath, key);
decryptFile(outputFilePath, decFilePath, key);

// 文件加密
function encryptFile(inputPath, outputPath, key) {
    const input = readBinaryFileSync(inputPath);
    const encryptedData = sm4.encrypt(input, key, {mode: 'ecb', padding: 'pkcs#7',output: 'array'});
    writeBinaryFileSync(outputPath, encryptedData);
}

// 文件解密
function decryptFile(inputPath, outputPath, key) {
    const encryptedData = readBinaryFileSync(inputPath);
    const decryptedData = sm4.decrypt(encryptedData, key, {mode: 'ecb', padding: 'pkcs#7', output:'array'});
    writeBinaryFileSync(outputPath, decryptedData);
}

function readBinaryFileSync(filePath) {
    try {
        const data = fs.readFileSync(filePath);
        const byteArray = [...data];
        return byteArray;
    } catch (err) {
        console.error('Error reading binary file:', err);
        return null;
    }
}

function writeBinaryFileSync(filePath, byteArray) {
    try {
        const buffer = Buffer.from(byteArray);
        fs.writeFileSync(filePath, buffer);
        console.log('Binary file written successfully.');
    } catch (err) {
        console.error('Error writing binary file:', err);
    }
}
GuoHuaijian commented 1 year ago

@changhr2013 谢谢 已经解决了 因为需求需要加密超大文件所以这个库并不适合流的方式读取加密 需要自己单独处理每块填充pkcs#7格式

JuneAndGreen commented 1 year ago

基于 TypedArray 的实现可以参考此实现:https://github.com/Cubelrti/sm-crypto-v2