You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用createCipheriv替代已弃用的createCipher处理大文件并解决未知密码错误

替换已弃用的createCipher为createCipheriv解决"Unknown cipher"错误

问题背景

原有代码使用已弃用的crypto.createCipher()/crypto.createDecipher()处理大文件加密解密,替换为createCipheriv()时出现Error: Unknown cipher错误,同时需要修正密钥生成、IV(初始化向量)的处理逻辑——因为createCipheriv要求显式指定IV和标准算法名称。

错误原因

  1. 算法名称不规范:createCipheriv需要使用完整的算法标识(如aes-256-cbc),而非简化的aes256;
  2. 缺少显式IV处理:createCipher会自动生成IV并嵌入输出,但createCipheriv需要手动生成、存储IV,解密时再读取;
  3. 密钥格式不匹配:AES-256要求32字节密钥,原有密钥生成逻辑输出的是64字符的Hex字符串,需转换为Buffer格式。

完整修正代码

1. 密钥生成模块(getCipherKey.js)

修正密钥格式,输出符合AES-256要求的32字节Buffer:

const CryptoJS = require('crypto-js');

function getCipherKey(password) {
  // 生成SHA256哈希,转为32字节Buffer
  const hash = CryptoJS.SHA256(password);
  return Buffer.from(hash.toString(CryptoJS.enc.Hex), 'hex');
}

module.exports = getCipherKey;

2. 加密代码

生成随机IV并写入加密文件开头,使用标准算法aes-256-cbc:

const fs = require('fs');
const zlib = require('zlib');
const path = require('path');
const crypto = require('crypto');
const getCipherKey = require('./getCipherKey');

function encrypt({ file, password }) {
  // 生成16字节随机IV(AES块大小固定为16字节)
  const iv = crypto.randomBytes(16);
  const cipherKey = getCipherKey(password);
  // 使用标准算法名称初始化加密器
  const cipher = crypto.createCipheriv('aes-256-cbc', cipherKey, iv);

  const readStream = fs.createReadStream(file);
  const zip = zlib.createGzip();
  const writeStream = fs.createWriteStream(path.join(file + ".enc"));

  // 先写入IV到文件开头,解密时需要读取
  writeStream.write(iv);

  readStream
    .pipe(zip)
    .pipe(cipher)
    .pipe(writeStream);
}

encrypt({ file: './video.mp4', password: 'dogzrgr8' });

3. 解密代码

先读取文件开头的16字节IV,再初始化解密器:

const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
const getCipherKey = require('./getCipherKey');

function decrypt({ file, password }) {
  const cipherKey = getCipherKey(password);
  const readStream = fs.createReadStream(file);
  
  // 先读取文件开头的16字节IV
  readStream.once('data', (ivChunk) => {
    const iv = ivChunk.slice(0, 16);
    const decipher = crypto.createDecipheriv('aes-256-cbc', cipherKey, iv);
    const unzip = zlib.createUnzip();
    // 替换后缀避免重复追加
    const writeStream = fs.createWriteStream(path.join(file.replace('.enc', '.unenc')));

    // 处理剩余数据并串联流
    readStream
      .pipe(decipher)
      .pipe(unzip)
      .pipe(writeStream);
  });
}

decrypt({ file: './video.mp4.enc', password: 'dogzrgr8' });

关键修改点说明

  • 算法名称:将aes256改为aes-256-cbc,这是Node.js crypto模块支持的标准算法标识;
  • IV处理:加密时生成随机IV并写入文件头部,解密时优先读取IV再初始化解密器;
  • 密钥格式:将Hex字符串转换为Buffer,确保密钥长度符合AES-256的32字节要求;
  • 文件命名:解密时替换.enc后缀为.unenc,避免出现xxx.enc.unenc这类冗余文件名。

内容的提问来源于stack exchange,提问作者Ranjith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 13:31:01