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

AES-192-CBC加密正常但解密失败,请求技术协助

问题排查与修复方案

你的AES-192-CBC解密失败核心原因有三个,逐一解决即可:

1. IV未复用,解密时生成新IV导致不匹配

AES-CBC模式要求加密和解密必须使用完全相同的IV,你当前加密时生成的IV没有返回给前端,解密时又重新生成新的随机IV,这直接导致解密失败。

2. 密钥生成不一致

convertKey函数每次调用都会生成新的随机盐,PBKDF2算法的密钥是基于密码+盐生成的,加密和解密用同一个密码但不同盐,生成的密钥完全不同,自然无法解密。必须把加密时用的盐也返回给前端,解密时复用该盐。

3. 解密函数参数不匹配

decrypt函数定义仅接收data和key两个参数,但解密路由里传了三个参数(encryptedData, key, ivHex),导致传入的ivHex根本没被使用,函数内部还是用了新生成的IV。


修复后的完整代码

const crypto = require('crypto');
// 假设cryptRouter和logger已提前定义

// Create an initialization vector (IV)
const generateInitializationVector = () => {
  return crypto.randomBytes(16); // 16 bytes = 128 bits
};

// Encrypt the data
function encrypt(data, key, iv) {
  const cipher = crypto.createCipheriv('aes-192-cbc', key, iv);
  let encrypted = cipher.update(data, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return encrypted;
}

// Decrypt the data
function decrypt(data, key, iv) {
  const decipher = crypto.createDecipheriv('aes-192-cbc', key, iv);
  let decrypted = decipher.update(data, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

// Convert key to a 24-byte Buffer using PBKDF2
function convertKey(keyHex, salt) {
  const iterations = 100000; // Number of iterations
  const keyLength = 24; // Desired key length in bytes

  // 加密时传null则生成新盐,解密时传入加密返回的盐
  const usedSalt = salt || crypto.randomBytes(16);
  const key = crypto.pbkdf2Sync(keyHex, usedSalt, iterations, keyLength, 'sha512');
  return { key, salt: usedSalt };
}

// Encryption route
cryptRouter.post('/encrypt', (req, res) => {
  try {
    const originalData = req.body.data;
    const keyHex = req.body.key;

    if (!originalData || !keyHex) {
      return res.status(400).json({ error: 'Data and key are required' });
    }

    const { key, salt } = convertKey(keyHex); // 生成密钥和盐
    const iv = generateInitializationVector(); // 生成IV
    const encryptedData = encrypt(originalData, key, iv);

    // 返回加密数据、盐、IV(都转成hex字符串方便前端存储/传输)
    res.json({
      encryptedData,
      salt: salt.toString('hex'),
      iv: iv.toString('hex')
    });
  } catch (error) {
    logger.error('Encryption error:', error);
    res.status(500).json({ error: 'Encryption failed' });
  }
});

// Decryption route
cryptRouter.post('/decrypt', (req, res) => {
  try {
    const encryptedData = req.body.data;
    const keyHex = req.body.key;
    const saltHex = req.body.salt;
    const ivHex = req.body.iv;

    if (!encryptedData || !keyHex || !saltHex || !ivHex) {
      return res.status(400).json({ error: 'Encrypted data, key, salt, and IV are required' });
    }

    // 将hex字符串转回Buffer
    const salt = Buffer.from(saltHex, 'hex');
    const iv = Buffer.from(ivHex, 'hex');

    const { key } = convertKey(keyHex, salt); // 用加密时的盐生成相同密钥
    const decryptedData = decrypt(encryptedData, key, iv);

    res.json({ decryptedData });
  } catch (catchError) {
    logger.error('Error in decryption route:', catchError);
    res.status(500).json({ error: 'Decryption failed' });
  }
});

module.exports = cryptRouter;

关键修复点说明

  • 加密时将盐、IV、加密数据一起返回给前端,解密时前端需要把这三个参数都传回来
  • 修改convertKey函数,支持传入已有的盐,保证加密解密生成相同密钥
  • 修正decrypt函数的参数,接收传入的IV而非重新生成
  • 所有二进制数据(盐、IV)转成hex字符串传输,避免二进制传输的编码问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 08:52:36