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

如何在原生JavaScript中实现字符串的AES加解密且规避不合规第三方库

原生JavaScript AES字符串加解密实现方案

方案说明

本方案完全基于浏览器/Node.js内置的原生Web Crypto API实现,无任何第三方依赖,不存在许可证合规问题,完全满足你的使用要求。
采用AES-GCM加密模式,自带密文完整性校验,安全性远高于传统的CBC、ECB模式;密钥通过PBKDF2从输入密码派生,避免弱密码直接作为加密密钥的安全风险。

完整实现代码

// 将字符串转ArrayBuffer
function stringToArrayBuffer(str) {
  return new TextEncoder().encode(str);
}

// 将ArrayBuffer转Base64字符串
function arrayBufferToBase64(buf) {
  return btoa(String.fromCharCode(...new Uint8Array(buf)));
}

// 将Base64字符串转ArrayBuffer
function base64ToArrayBuffer(b64) {
  const binary = atob(b64);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < binary.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  return bytes.buffer;
}

// 从密码派生AES密钥
async function getKeyFromPassword(password, salt) {
  const passwordKey = await crypto.subtle.importKey(
    "raw",
    stringToArrayBuffer(password),
    { name: "PBKDF2" },
    false,
    ["deriveKey"]
  );
  return crypto.subtle.deriveKey(
    {
      name: "PBKDF2",
      salt: salt,
      iterations: 100000,
      hash: "SHA-256",
    },
    passwordKey,
    { name: "AES-GCM", length: 256 },
    false,
    ["encrypt", "decrypt"]
  );
}

// AES加密函数
async function aesEncrypt(plainText, password) {
  // 生成随机盐值和IV
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const key = await getKeyFromPassword(password, salt);
  
  // 加密
  const encrypted = await crypto.subtle.encrypt(
    { name: "AES-GCM", iv: iv },
    key,
    stringToArrayBuffer(plainText)
  );
  
  // 拼接盐值、IV、密文,统一转Base64方便存储传输
  const resultBuffer = new Uint8Array(salt.length + iv.length + encrypted.byteLength);
  resultBuffer.set(salt, 0);
  resultBuffer.set(iv, salt.length);
  resultBuffer.set(new Uint8Array(encrypted), salt.length + iv.length);
  return arrayBufferToBase64(resultBuffer.buffer);
}

// AES解密函数
async function aesDecrypt(encryptedBase64, password) {
  const encryptedBuffer = base64ToArrayBuffer(encryptedBase64);
  // 拆分盐值、IV、密文
  const salt = encryptedBuffer.slice(0, 16);
  const iv = encryptedBuffer.slice(16, 16 + 12);
  const data = encryptedBuffer.slice(16 + 12);
  
  const key = await getKeyFromPassword(password, salt);
  const decrypted = await crypto.subtle.decrypt(
    { name: "AES-GCM", iv: iv },
    key,
    data
  );
  return new TextDecoder().decode(decrypted);
}

使用示例

对应你给出的业务场景,使用方式如下:

// 你的业务参数
const Json = { /* 你的JSON数据 */ };
const pass = "你的加密密码";
const fnm = "encrypted_data.txt";

(async () => {
  // 替换原有的加密逻辑
  var jsn = JSON.stringify(Json);
  var encrypted = await aesEncrypt(jsn, pass);
  saveStringToFile(encrypted, fnm);

  // 解密验证示例
  const decryptedStr = await aesDecrypt(encrypted, pass);
  const decryptedJson = JSON.parse(decryptedStr);
})();

注意事项

  • 如果你在Node.js环境使用,15以上版本已内置crypto.webcrypto,仅需把代码中的crypto替换为require('crypto').webcrypto即可正常运行
  • 加密输出的Base64字符串已经包含了随机盐、IV和认证标签,无需单独存储其他参数,直接保存即可
  • 密钥派生的迭代次数默认设为100000,你可以根据安全需求和性能要求调整,迭代次数越高暴力破解难度越大,加解密耗时也会相应增加

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:30:02