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


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

相关推荐
春天花会开13118 小时前
Kubernetes 高可用架构实战指南
架构
码云之上19 小时前
万星入坞·其三:SDK 轻量组件如何优雅地"点亮"
性能优化·架构·前端框架
枫叶林FYL19 小时前
【强化学习】3 双系统持续强化学习:快速迁移与元知识整合架构手册
人工智能·机器学习·架构
AI科技星19 小时前
哥德巴赫猜想1+1基于平行素数对等腰梯形网格拓扑与素数渐近密度的大偶数满填充完备性证明
人工智能·线性代数·架构·概率论·学习方法
小短腿的代码世界19 小时前
信号路由风暴:Qt算法交易系统的高频信号分发架构
qt·算法·架构
2301_7807896620 小时前
手游遇到攻击为什么要用SDK游戏盾手游遇到攻击为什么要用 SDK 游戏盾?
安全·web安全·游戏·架构·kubernetes·ddos
中小企业实战军师刘孙亮20 小时前
小微企业生存发展指南:从求稳到扩张的实战策略-佛山鼎策创局破局增长咨询
架构·产品运营·音视频·制造·业界资讯
sanduo11221 小时前
什么是优秀的部署架构?
架构
国科安芯21 小时前
ASP7A84AS与主流架构兼容替代及系统级电源完整性解决方案的深度研究
单片机·嵌入式硬件·架构
JZC_xiaozhong21 小时前
研发体系集成架构:打通OA与PLM的核心参考
大数据·架构·流程自动化·数据集成与应用集成