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

C# .NET与JavaScript的AES加解密互通实现问题咨询

问题根因

你之前的代码存在三个核心不匹配点,导致加解密失败:

  • 工作模式错误:.NET 中 Aes 类默认使用 CBC 模式,你代码中配置的ECB模式和供应商逻辑完全不匹配;且ECB模式不需要IV,和供应商代码显式取密钥前16位作为IV的逻辑冲突。
  • 密钥解析逻辑错误:CryptoJS 的 AES 接口如果直接传入字符串类型的密钥,会默认将其作为口令,走 OpenSSL 兼容的EVP_BytesToKey算法派生实际密钥和IV,不会直接将字符串按UTF8编码转为字节作为原始AES密钥,和C#端直接取UTF8字节作为key/IV的逻辑不一致。
  • 冗余编码错误:你对密文做了两次无意义的Base64转码操作,破坏了原始密文结构。
可互通实现方案

供应商C#代码的固定AES参数如下,两端严格对齐即可互通:

  • 工作模式:CBC
  • 填充方式:PKCS7
  • 密钥:传入的key字符串按UTF8编码转字节,key长度必须为16/24/32位,分别对应AES-128/AES-192/AES-256,否则C#端会直接抛出参数异常
  • IV:取key字符串前16位,按UTF8编码转字节

CryptoJS 版本实现(和你现有技术栈一致)

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

// 对应C#端Encrypt方法
function aesEncrypt(plainText, key) {
  // 显式按UTF8解析key和IV,避免CryptoJS自动做密钥派生
  const keyBytes = CryptoJS.enc.Utf8.parse(key);
  const ivBytes = CryptoJS.enc.Utf8.parse(key.slice(0, 16));

  const encrypted = CryptoJS.AES.encrypt(
    CryptoJS.enc.Utf8.parse(plainText),
    keyBytes,
    {
      iv: ivBytes,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    }
  );
  // 直接返回Base64格式密文,和C#端输出格式完全一致
  return encrypted.toString();
}

// 对应C#端Decrypt方法
function aesDecrypt(cipherTextBase64, key) {
  const keyBytes = CryptoJS.enc.Utf8.parse(key);
  const ivBytes = CryptoJS.enc.Utf8.parse(key.slice(0, 16));

  const decrypted = CryptoJS.AES.decrypt(
    cipherTextBase64,
    keyBytes,
    {
      iv: ivBytes,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    }
  );
  return decrypted.toString(CryptoJS.enc.Utf8);
}

// 测试示例
const testKey = "1234567890123456"; // 16位密钥对应AES-128
const testPlain = "跨端AES互通测试 test123!@#";
const cipher = aesEncrypt(testPlain, testKey);
console.log("加密后密文:", cipher);
const plain = aesDecrypt(cipher, testKey);
console.log("解密后明文:", plain); // 输出和原始明文一致即为正常

Node.js 原生crypto模块实现(无第三方依赖)

如果不想引入第三方依赖,可以直接用Node.js内置的crypto模块实现,性能更好:

const crypto = require('crypto');

function aesEncrypt(plainText, key) {
  const iv = key.slice(0, 16);
  // 根据密钥长度自动匹配对应算法:16位=aes-128-cbc、24位=aes-192-cbc、32位=aes-256-cbc
  const algorithm = `aes-${key.length * 8}-cbc`;
  const cipher = crypto.createCipheriv(
    algorithm,
    Buffer.from(key, 'utf8'),
    Buffer.from(iv, 'utf8')
  );
  let encrypted = cipher.update(plainText, 'utf8', 'base64');
  encrypted += cipher.final('base64');
  return encrypted;
}

function aesDecrypt(cipherTextBase64, key) {
  const iv = key.slice(0, 16);
  const algorithm = `aes-${key.length * 8}-cbc`;
  const decipher = crypto.createDecipheriv(
    algorithm,
    Buffer.from(key, 'utf8'),
    Buffer.from(iv, 'utf8')
  );
  let decrypted = decipher.update(cipherTextBase64, 'base64', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

注意:如果对接时出现解密乱码,先确认双方使用的key完全一致,且key长度符合AES要求,不要包含多余的空格、换行符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 02:24:21