安全不是可选项:理解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 权限模型:如何设计一个灵活的权限系统


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

相关推荐
会周易的程序员6 小时前
microLog 的本地日志读取接口 log_reader — 本地日志文件读取工具开发指南
linux·物联网·架构·嵌入式·日志·iot·aiot
无心水7 小时前
【全域智能营销实战】2、Spring AI 模块化架构深度解读:从 1.0 到 2.0 的演进与最佳实践
人工智能·spring·架构·harness·顶尖架构师·全域智能营销·harmess
HavenlonLabs7 小时前
Havenlon 对抗性完整(十七):安全不是“防住攻击”,而是控制失败方式
网络·人工智能·架构·安全威胁分析·安全架构·havenlon
doiito(Do It Together)7 小时前
media_agent 进化之路:把 Gliding Horse 的 Agent 超能力注入 ComfyUI,让图片生成自己“学会”优化
人工智能·架构·rust·knowledge graph
触底反弹8 小时前
🔥 从点积到 Transformer:我终于搞懂大模型是怎么"猜"出下一个词的了
人工智能·机器学习·架构
2601_962502908 小时前
服装点胶点钻设备的算法架构与工艺适配分析
架构
-dzk-10 小时前
【系统架构设计师】案例分析篇
开发语言·数据结构·python·算法·架构·系统架构·架构设计
凡泰AI10 小时前
从个人用AI到企业用AI,如何为企业部署一套私有化Agent智能体运行时,将AI变成企业的基础设施
人工智能·ai·架构·agent·cio
柒和远方10 小时前
Phase 7.4 学习博客:为什么多 API 项目需要 Swagger / OpenAPI
前端·后端·架构
mONESY10 小时前
AI Loop 自动化工程实践,放弃手工调 Prompt,循环才是标准答案!
架构