安全不是可选项:理解AES+RSA双重加密

F06 | 安全不是可选项:理解 AES+RSA 双重加密

🆓 免费文章 | 安全篇


为什么需要加密通信?

很多新手开发者的 API 是这样的:

复制代码
POST /api/user/login
{"username": "admin", "password": "111111"}

如果你的 App 在公共 WiFi 环境下运行,中间人可以直接抓包看到明文密码。即使用了 HTTPS,也存在证书伪造、中间人攻击等风险。

生产级别的应用,必须在 HTTPS 的基础上,再加一层应用层加密。


两种加密算法的特点

AES:对称加密,速度快

  • 同一个密钥,既能加密也能解密

  • 速度极快,适合加密大量数据(如整个请求体)

  • 问题:如何安全地传递这个密钥?

    AES 密钥:一把锁,既能锁也能开
    问题:怎么把这把锁安全地给对方?

RSA:非对称加密,安全传递密钥

  • 公钥加密,私钥解密

  • 服务器公开公钥,自己保留私钥

  • 速度慢,只适合加密少量数据(如 AES 密钥)

    RSA 公钥:一个只能锁不能开的锁
    RSA 私钥:只有服务器有的开锁钥匙
    用法:把 AES 密钥放进 RSA 锁里,发给服务器


本项目的双重加密方案

复制代码
前端                              后端
 │                                 │
 │ 1. 生成随机 AES 密钥 (16字节)    │
 │                                 │
 │ 2. 获取服务器 RSA 公钥 ──────────┤ 返回 RSA 公钥
 │                                 │
 │ 3. RSA公钥加密(AES密钥) = encryptKey
 │                                 │
 │ 4. AES加密(请求体) = encryptData │
 │                                 │
 │ 5. 发送 { encryptKey, encryptData, sign }
 │                                 │
 │                   ┌─────────────┘
 │                   │ 6. RSA私钥解密 encryptKey → AES密钥
 │                   │ 7. AES解密 encryptData → 原始请求体
 │                   │ 8. 验证 sign 签名
 │                   │ 9. 处理业务逻辑
 │                   │ 10. AES加密响应体
 │ ←─────────────────┘
 │ 11. AES解密响应体 → 原始数据

关键代码剖析

前端(以 JavaScript 版为例)

复制代码
// pikachuNetwork.js 核心逻辑

// 1. 生成随机 AES 密钥
function generateAESKey() {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let key = ''
  for (let i = 0; i < 16; i++) {
    key += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  return key
}

// 2. RSA 加密 AES 密钥
function rsaEncrypt(data, publicKey) {
  const encrypt = new JSEncrypt()
  encrypt.setPublicKey(publicKey)
  return encrypt.encrypt(data)
}

// 3. AES 加密请求体
function aesEncrypt(data, key) {
  return CryptoJS.AES.encrypt(
    JSON.stringify(data),
    CryptoJS.enc.Utf8.parse(key),
    { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }
  ).toString()
}

// 发送请求
async function post(url, params) {
  const aesKey = generateAESKey()
  const encryptKey = rsaEncrypt(aesKey, store.serverPublicKey)
  const encryptData = aesEncrypt(params, aesKey)
  
  const response = await axios.post(url, {
    encryptKey,
    encryptData,
    sign: md5(sha1(JSON.stringify(params)))
  })
  
  // 解密响应
  return aesDecrypt(response.data.encryptData, aesKey)
}

后端(Kotlin 版)

复制代码
// RequestBodyAdvice:全局解密拦截器
@RestControllerAdvice
class DecryptRequestBodyAdvice : RequestBodyAdviceAdapter() {
    
    override fun beforeBodyRead(
        inputMessage: HttpInputMessage,
        parameter: MethodParameter,
        targetType: Type,
        converterType: Class<out HttpMessageConverter<*>>
    ): HttpInputMessage {
        // 读取请求体
        val body = inputMessage.body.readBytes().toString(Charsets.UTF_8)
        val request = objectMapper.readValue(body, EncryptRequest::class.java)
        
        // RSA 解密 AES 密钥
        val aesKey = rsaDecrypt(request.encryptKey, privateKey)
        
        // AES 解密请求体
        val decryptedBody = aesDecrypt(request.encryptData, aesKey)
        
        return DecryptedHttpInputMessage(inputMessage, decryptedBody)
    }
}

签名验证:防篡改

除了加密,还需要防止请求被篡改:

复制代码
// 前端生成签名
function signature(pwd) {
  return md5(sha1(pwd).toUpperCase())
}

// 后端验证签名
fun verifySign(params: Map<String, Any>, sign: String): Boolean {
    val calculated = md5(sha1(params.toSortedString()).toUpperCase())
    return calculated == sign
}

给初学者的建议

你不需要现在就完全理解每一行加密代码。在付费课程里,我们会:

  1. 直接给你完整的加密工具类代码
  2. 解释每个步骤的用途
  3. 手把手接入到你的项目里

现在只需要记住:生产级的 API 必须加密,本课程提供了完整的可复用实现。


下一篇

F07 → RBAC 权限模型:如何设计一个灵活的权限系统


本文为免费文章,转载请注明出处。

相关推荐
wapicn991 小时前
微服务架构下的数据核验设计,API接入最佳实践
微服务·云原生·架构
Ghost Face...1 小时前
龙芯2K1000 SoC启动全流程与架构解析
架构
侠客工坊2 小时前
移动端 RPA 的架构重构:基于侠客工坊多模态视觉大模型的自动化调度系统压测复盘
人工智能·智能手机·重构·架构·rpa·数字员工·侠客工坊
liang_jy3 小时前
Android 架构中的统一分发与策略路由
android·架构
hsjcjh3 小时前
深度技术拆解:2026年Gemini 3.1 Pro镜像官网架构与推理能力全面解析(附国内实测方案)
架构
若兰幽竹3 小时前
【从零开始编写数据库系统:架构设计与实现】第5章:查询执行引擎与火山模型
数据库·架构·数据库内核·toydb
逻辑诗篇3 小时前
破核拆解:PCIE719——基于Xilinx Zynq UltraScale+的高性能SAS扩展卡设计
fpga开发·架构
wenzhangli74 小时前
Ooder A2UI 核心架构深度解析:WEB 拦截层的设计与实现
前端·架构
福大大架构师每日一题4 小时前
openclaw v2026.4.24 发布:Google Meet 深度集成、DeepSeek V4 上线、浏览器自动化与插件架构全面升级
运维·架构·自动化·openclaw
身如柳絮随风扬4 小时前
深度解析 Elasticsearch 搜索服务:核心原理、架构与优化实践
大数据·elasticsearch·架构