如何在Node.js中使用AES-CBC算法加解密大文件并实现加密进度指示器
Node.js大文件加密新增进度指示器实现方案
核心逻辑是通过统计可读流已读取的字节数,和源文件总大小的比值计算实时进度,同时补充了原代码遗漏的初始向量(IV)存储逻辑,避免加密后无法解密的问题。
完整实现代码
import fs from 'fs'; import zlib from 'zlib'; import crypto from 'crypto'; // 配置参数 const SOURCE_FILE = 'X:/File.mp4'; const ENC_FILE = 'X:/File.mp4.enc'; const PASSWORD = 'SomePassword'; // 进度更新节流时间,避免频繁刷新控制台 const PROGRESS_UPDATE_INTERVAL = 500; // 1. 获取源文件总大小 const { size: totalSize } = fs.statSync(SOURCE_FILE); let processedSize = 0; let lastUpdateTime = Date.now(); // 2. 生成加密所需参数 const initVect = crypto.randomBytes(16); const hashedPassword = crypto.createHash('sha256').update(PASSWORD).digest(); const cipher = crypto.createCipheriv('aes-256-cbc', hashedPassword, initVect); // 3. 创建读写流和压缩流 const fread = fs.createReadStream(SOURCE_FILE); const fwrite = fs.createWriteStream(ENC_FILE); const gzipStream = zlib.createGzip(); // 4. 先把IV写入加密文件开头(解密时需要先读取前16字节获取IV) fwrite.write(initVect); // 5. 监听可读流的data事件统计已处理大小,计算进度 fread.on('data', (chunk) => { processedSize += chunk.length; // 节流更新进度,避免控制台刷新过于频繁 if (Date.now() - lastUpdateTime > PROGRESS_UPDATE_INTERVAL) { const progress = ((processedSize / totalSize) * 100).toFixed(2); // 用\r回到行首实现单行进度刷新,不会产生多行日志 process.stdout.write(`\r加密进度: ${progress}% | 已处理: ${(processedSize / 1024 / 1024).toFixed(2)}MB / ${(totalSize / 1024 / 1024).toFixed(2)}MB`); lastUpdateTime = Date.now(); } }); // 6. 流处理完成回调 fwrite.on('finish', () => { // 最后输出100%进度,换行 process.stdout.write(`\r加密进度: 100.00% | 已处理: ${(totalSize / 1024 / 1024).toFixed(2)}MB / ${(totalSize / 1024 / 1024).toFixed(2)}MB\n`); console.log('加密完成,IV已存储到加密文件开头'); }); // 7. 错误监听 fread.on('error', (err) => console.error('读取源文件失败:', err)); fwrite.on('error', (err) => console.error('写入加密文件失败:', err)); cipher.on('error', (err) => console.error('加密失败:', err)); // 启动流管道 fread.pipe(gzipStream).pipe(cipher).pipe(fwrite);
注意事项
- 解密时需要先从加密文件读取前16个字节作为IV,剩下的内容才是加密后的压缩数据,按
解密 -> 解压的顺序处理即可还原原文件 - 如果你不需要单行刷新进度,把
process.stdout.write里的\r去掉换成console.log即可,会逐行输出进度 - 进度计算用的是源文件的已读取大小,和压缩、加密后的大小无关,进度统计准确,不会受压缩率影响
内容的提问来源于stack exchange,提问作者masamune756
相关产品推荐
相关产品推荐

