🔒 前后端 AES 加密解密实战(Vue3 + Node.js)

各位掘友好,我是庚云。

在前后端交互中,如果账号密码明文传输,很容易被窃取 ⚠️。虽然 HTTPS 已经可以保证传输安全,但很多业务场景下,我们还会在此基础上 额外增加一层 AES 加密,提升安全性。

今天分享一个完整的 AES 双向加解密 Demo

  • 前端(Vue3 + Vite):加密用户输入的密码,再传给后端
  • 后端(Node.js + Express):解密密码,校验登录
  • 后端返回一个加密的 token,前端再解密出来

👉 实现一个 前端加密 → 后端解密 → 后端加密 → 前端解密 的完整闭环。


📂 项目结构

bash 复制代码
aes-demo/
├── backend/                  # Node.js + Express 后端
│   ├── index.js              # 主入口,API 服务
│   ├── package.json
│   └── node_modules/
│
├── frontend/                 # Vue3 前端
│   ├── src/
│   │   ├── api/
│   │   │   └── login.ts      # 登录 API
│   │   ├── utils/
│   │   │   └── aes.ts        # AES 工具方法(加密/解密)
│   │   ├── views/
│   │   │   └── Login.vue     # 登录页面
│   │   ├── main.ts           # Vue 应用入口
│   │   └── index.html
│   ├── package.json
│   └── node_modules/

🖥️ 一、后端实现(Node.js 解密)

后端负责:

  1. 解密前端传过来的密码;
  2. 验证账号密码;
  3. 登录成功后,返回一个 加密后的 token

📁 backend/index.js

javascript 复制代码
import express from 'express'
import bodyParser from 'body-parser'
import crypto from 'crypto'
import cors from 'cors'

const app = express()
app.use(cors())
app.use(bodyParser.json())

// AES 配置(和前端保持一致)
const KEY = Buffer.from('1234567812345678', 'utf8')  // 16 字节
const IV = Buffer.from('8765432187654321', 'utf8')   // 16 字节

// 解密
function decryptAES(cipherText) {
  const decipher = crypto.createDecipheriv('aes-128-cbc', KEY, IV)
  let decrypted = decipher.update(cipherText, 'base64', 'utf8')
  decrypted += decipher.final('utf8')
  return decrypted
}

// 加密
function encryptAES(text) {
  const cipher = crypto.createCipheriv('aes-128-cbc', KEY, IV)
  let encrypted = cipher.update(text, 'utf8', 'base64')
  encrypted += cipher.final('base64')
  return encrypted
}

app.post('/api/login', (req, res) => {
  const { username, password } = req.body
  const decryptedPwd = decryptAES(password)

  if (username === 'admin' && decryptedPwd === '123456') {
    // 登录成功,返回加密后的 token
    const token = encryptAES('this-is-a-secret-token')
    res.json({ code: 0, msg: '登录成功', token })
  } else {
    res.status(401).json({ code: 1, msg: '账号或密码错误' })
  }
})

app.listen(3001, () => {
  console.log('后端服务已启动:http://localhost:3001')
})

🌐 二、前端实现(Vue3 加密)

前端负责:

  1. 输入密码 → AES 加密 → 传给后端;
  2. 拿到后端返回的加密 token → AES 解密 → 得到明文。

📁 frontend/utils/aes.ts

javascript 复制代码
import CryptoJS from 'crypto-js'

// 和后端约定的 KEY 和 IV
const KEY = CryptoJS.enc.Utf8.parse('1234567812345678')
const IV = CryptoJS.enc.Utf8.parse('8765432187654321')

// 加密
export function encryptAES(text: string): string {
  const encrypted = CryptoJS.AES.encrypt(text, KEY, {
    iv: IV,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  })
  return encrypted.toString()
}

// 解密
export function decryptAES(cipherText: string): string {
  const decrypted = CryptoJS.AES.decrypt(cipherText, KEY, {
    iv: IV,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  })
  return decrypted.toString(CryptoJS.enc.Utf8)
}

📁 frontend/api/login.ts

javascript 复制代码
import axios from 'axios'
import { encryptAES } from '@/utils/aes'

export function login(username: string, password: string) {
  const encryptedPwd = encryptAES(password)

  return axios.post('http://localhost:3001/api/login', {
    username,
    password: encryptedPwd,
  })
}

📁 frontend/views/Login.vue

javascript 复制代码
<template>
  <div>
    <input v-model="username" placeholder="用户名" />
    <input v-model="password" type="password" placeholder="密码" />
    <button @click="handleLogin">登录</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { login } from '@/api/login'
import { decryptAES } from '@/utils/aes'

const username = ref('admin')
const password = ref('123456')

const handleLogin = async () => {
  try {
    const res = await login(username.value, password.value)
    if (res.data.code === 0) {
      const token = decryptAES(res.data.token)
      alert(`登录成功 ✅ 解密后的 token:${token}`)
    } else {
      alert(res.data.msg)
    }
  } catch (e) {
    alert('登录失败')
  }
}
</script>

📁 frontend/main.ts

javascript 复制代码
import { createApp } from 'vue'
import Login from './views/Login.vue'

createApp(Login).mount('#app')

📁 frontend/index.html

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Login AES Demo</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

📦 前端依赖安装

bash 复制代码
npm create vite@latest frontend
# 选择 vue-ts 模板

cd frontend
npm install axios crypto-js
npm run dev

🚀 启动流程

bash 复制代码
# 启动后端
cd backend
npm install express body-parser cors
node index.js

# 启动前端
cd frontend
npm install
npm run dev

访问 👉 http://localhost:5173

输入用户名:admin,密码:123456

点击登录 → 会弹出 解密后的 token


📝 小结 & 注意事项

到这里,我们实现了一个完整的 AES 双向加解密 Demo

  1. 前端输入密码 → AES 加密 → 发给后端
  2. 后端解密 → 校验账号密码
  3. 登录成功 → 后端返回加密的 token
  4. 前端解密 token → 拿到明文

这样一来,即使有人截获了请求数据,也只会拿到密文,进一步提升安全性。

⚠️ 但在真实项目中,还需要注意:

  • AES key 长度:必须是 16/24/32 字节,分别对应 AES-128/192/256;
  • IV 向量:最好不要写死,而是每次随机生成,再跟密文一起传给对方;
  • HTTPS 仍然必须:AES 只是额外的加密层,不能替代 HTTPS;
  • 不要重复使用固定 key:可以考虑结合动态密钥、RSA 非对称加密来提升安全性;
  • token 更推荐用 JWT:这个 demo 只是展示 AES 使用场景,实际项目中还要结合业务。
相关推荐
胡gh1 小时前
依旧性能优化,如何在浅比较上做文章,memo 满天飞,谁在裸奔?
前端·react.js·面试
大怪v1 小时前
超赞👍!优秀前端佬的电子布洛芬技术网站!
前端·javascript·vue.js
胡gh1 小时前
你一般用哪些状态管理库?别担心,Zustand和Redux就能说个10分钟
前端·面试·node.js
小厂永远得不到的男人2 小时前
基于 Spring Validation 实现全局参数校验异常处理
java·后端·架构
roamingcode3 小时前
Claude Code NPM 包发布命令
前端·npm·node.js·claude·自定义指令·claude code
码哥DFS3 小时前
NPM模块化总结
前端·javascript
灵感__idea3 小时前
JavaScript高级程序设计(第5版):代码整洁之道
前端·javascript·程序员
唐璜Taro4 小时前
electron进程间通信-IPC通信注册机制
前端·javascript·electron
陪我一起学编程5 小时前
创建Vue项目的不同方式及项目规范化配置
前端·javascript·vue.js·git·elementui·axios·企业规范
LinXunFeng5 小时前
Flutter - 详情页初始锚点与优化
前端·flutter·开源