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

如何安全加解密API响应JSON?寻求适配技术方案

可行的API响应加密/前端解密方案

你提到的bcrypt属于单向哈希算法,只能加密不能解密,完全不适合你的双向加解密需求。下面是基于对称加密算法的落地方案,推荐用AES-256-GCM(兼顾安全性和性能),直接上代码和关键说明:

核心逻辑

后端对响应的敏感字段(或整个JSON)进行加密,返回包含加密内容、初始化向量(IV)和认证标签的字符串;前端拿到后用相同密钥解密,还原原始数据。


后端加密实现(Node.js示例)

用Node.js内置crypto模块,无需额外安装依赖:

const crypto = require('crypto');

// 密钥用32字节(对应AES-256),从环境变量读取,绝对不能硬编码
const ENCRYPTION_KEY = Buffer.from(process.env.ENCRYPTION_KEY, 'hex');
// GCM模式推荐12字节的IV,每次加密必须生成新的
const IV_LENGTH = 12;

// 单个字符串加密函数
function encrypt(text) {
  const iv = crypto.randomBytes(IV_LENGTH);
  const cipher = crypto.createCipheriv('aes-256-gcm', ENCRYPTION_KEY, iv);
  
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  
  // 把IV和认证标签一起返回,前端解密必须用这两个值
  const authTag = cipher.getAuthTag().toString('hex');
  return `${iv.toString('hex')}:${authTag}:${encrypted}`;
}

// 加密响应对象的指定字段
function encryptResponse(rawData) {
  return {
    abc_key: encrypt(rawData.abc_key),
    cde_key: encrypt(rawData.cde_key)
  };
}

// 在API接口中使用
app.get('/api/secure-data', (req, res) => {
  const rawResponse = {
    abc_key: 'sdlnf-2343-325sdgdssg',
    cde_key: 'lkgh-3453-dtjdd-32423'
  };
  res.json(encryptResponse(rawResponse));
});

前端解密实现

方案1:原生Web Crypto API(推荐,无依赖)

// 密钥和后端保持一致,转成ArrayBuffer格式
const ENCRYPTION_KEY = hexToBuffer(process.env.REACT_APP_ENCRYPTION_KEY);

function hexToBuffer(hexStr) {
  return new Uint8Array(hexStr.match(/.{1,2}/g).map(byte => parseInt(byte, 16))).buffer;
}

async function decrypt(encryptedStr) {
  const [ivHex, authTagHex, encryptedHex] = encryptedStr.split(':');
  const iv = hexToBuffer(ivHex);
  const authTag = hexToBuffer(authTagHex);
  const encryptedData = hexToBuffer(encryptedHex);

  // 导入密钥
  const key = await window.crypto.subtle.importKey(
    'raw',
    ENCRYPTION_KEY,
    { name: 'AES-GCM' },
    false,
    ['decrypt']
  );

  // 解密并转回字符串
  const decryptedBuffer = await window.crypto.subtle.decrypt(
    { name: 'AES-GCM', iv, tag: authTag },
    key,
    encryptedData
  );
  return new TextDecoder().decode(decryptedBuffer);
}

// 调用示例
async function fetchSecureData() {
  const res = await fetch('/api/secure-data');
  const encryptedData = await res.json();
  const decryptedData = {
    abc_key: await decrypt(encryptedData.abc_key),
    cde_key: await decrypt(encryptedData.cde_key)
  };
  console.log('解密后数据:', decryptedData);
}

方案2:crypto-js库(兼容旧浏览器)

先安装依赖:npm install crypto-js

import CryptoJS from 'crypto-js';

const ENCRYPTION_KEY = CryptoJS.enc.Hex.parse(process.env.REACT_APP_ENCRYPTION_KEY);

function decrypt(encryptedStr) {
  const [ivHex, authTagHex, encryptedHex] = encryptedStr.split(':');
  const iv = CryptoJS.enc.Hex.parse(ivHex);
  const authTag = CryptoJS.enc.Hex.parse(authTagHex);
  const encryptedData = CryptoJS.enc.Hex.parse(encryptedHex);

  const decrypted = CryptoJS.AES.decrypt(
    { ciphertext: encryptedData, authTag },
    ENCRYPTION_KEY,
    { iv, mode: CryptoJS.mode.GCM, padding: CryptoJS.pad.NoPadding }
  );
  return decrypted.toString(CryptoJS.enc.Utf8);
}

// 使用方式和方案1一致

关键注意事项

  • 密钥安全:后端密钥必须存在环境变量中,前端密钥通过构建工具注入(比如React的REACT_APP_前缀变量),但纯前端场景下密钥可能被反编译获取,这种情况建议结合HTTPS+JWT,或考虑后端代理解密。
  • IV唯一性:每次加密必须生成新的随机IV,绝不能重复使用同一IV和密钥组合,否则会泄露密钥。
  • 完整性校验:GCM模式的认证标签必须和加密内容一起传递,前端解密时会自动验证,防止数据被篡改。
  • 加密范围:只加密敏感字段即可,无需加密整个JSON,减少性能开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 23:10:51