🎬 HoRain 云小助手个人主页

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

目录

⛳️ 推荐

一、加密基础原则

二、使用Web Crypto API(原生方案)

1. 创建加密工具类

2. 在组件中使用

三、集成CryptoJS(兼容旧浏览器)

1. 安装库

2. 封装加密工具

四、结合状态管理加密

1. Pinia存储加密示例

2. 安全使用方式

五、混合加密方案(非对称+对称)

六、安全增强措施

七、不同场景选型建议

八、注意事项


 


一、加密基础原则

  1. 前端加密不能替代HTTPS(仅作为额外保护层)
  2. 避免硬编码密钥(可通过服务端动态获取)
  3. 敏感数据必须服务端二次加密
  4. 优先使用现代加密标准(AES-GCM、RSA-OAEP等)

二、使用Web Crypto API(原生方案)

1. 创建加密工具类
// utils/crypto.js
const encoder = new TextEncoder()
const decoder = new TextDecoder()

export async function generateKey() {
  return window.crypto.subtle.generateKey(
    { name: "AES-GCM", length: 256 },
    true, // 是否可导出
    ["encrypt", "decrypt"]
  )
}

export async function encryptData(plainText, key) {
  const iv = window.crypto.getRandomValues(new Uint8Array(12))
  const encoded = encoder.encode(plainText)
  
  const cipherText = await window.crypto.subtle.encrypt(
    { name: "AES-GCM", iv },
    key,
    encoded
  )

  return { iv, cipherText }
}

export async function decryptData({ iv, cipherText }, key) {
  try {
    const decrypted = await window.crypto.subtle.decrypt(
      { name: "AES-GCM", iv },
      key,
      cipherText
    )
    
    return decoder.decode(decrypted)
  } catch (error) {
    console.error("解密失败:", error)
    return null
  }
}
2. 在组件中使用
<script setup>
import { ref } from 'vue'
import { generateKey, encryptData, decryptData } from '@/utils/crypto'

const key = ref(null)
const secretMessage = ref('')
const encryptedData = ref(null)

// 生成密钥
generateKey().then(k => key.value = k)

const handleEncrypt = async () => {
  if (!key.value) return
  encryptedData.value = await encryptData(secretMessage.value, key.value)
}

const handleDecrypt = async () => {
  if (!encryptedData.value) return
  const decrypted = await decryptData(encryptedData.value, key.value)
  console.log('解密结果:', decrypted)
}
</script>

三、集成CryptoJS(兼容旧浏览器)

1. 安装库
npm install crypto-js
2. 封装加密工具
// utils/crypto-utils.js
import CryptoJS from 'crypto-js'

const SECRET_KEY = import.meta.env.VITE_CRYPTO_KEY // 从环境变量获取

export const encrypt = (text) => {
  const encrypted = CryptoJS.AES.encrypt(
    text, 
    CryptoJS.enc.Utf8.parse(SECRET_KEY),
    { 
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
      iv: CryptoJS.enc.Utf8.parse(SECRET_KEY.slice(0, 16)) 
    }
  )
  return encrypted.toString()
}

export const decrypt = (cipherText) => {
  const decrypted = CryptoJS.AES.decrypt(
    cipherText,
    CryptoJS.enc.Utf8.parse(SECRET_KEY),
    {
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
      iv: CryptoJS.enc.Utf8.parse(SECRET_KEY.slice(0, 16))
    }
  )
  return decrypted.toString(CryptoJS.enc.Utf8)
}

四、结合状态管理加密

1. Pinia存储加密示例
// stores/user.js
import { defineStore } from 'pinia'
import { encrypt, decrypt } from '@/utils/crypto-utils'

export const useUserStore = defineStore('user', {
  state: () => ({
    _encryptedToken: null, // 加密后的token
    publicInfo: {}
  }),
  getters: {
    token: (state) => {
      return state._encryptedToken ? decrypt(state._encryptedToken) : null
    }
  },
  actions: {
    setToken(rawToken) {
      this._encryptedToken = encrypt(rawToken)
    }
  },
  persist: {
    paths: ['_encryptedToken', 'publicInfo']
  }
})
2. 安全使用方式
<script setup>
import { useUserStore } from '@/stores/user'

const userStore = useUserStore()

// 存储时自动加密
const login = async () => {
  const res = await fetch('/api/login')
  const { token } = await res.json()
  userStore.setToken(token) // 自动加密存储
}

// 读取时自动解密
const checkAuth = () => {
  console.log('当前Token:', userStore.token) // 透明解密
}
</script>

五、混合加密方案(非对称+对称)

// 结合RSA和AES
async function hybridEncrypt(plainText, publicKey) {
  // 1. 生成临时AES密钥
  const aesKey = await generateAESKey()
  
  // 2. 用AES加密数据
  const { cipherText, iv } = await aesEncrypt(plainText, aesKey)
  
  // 3. 用RSA加密AES密钥
  const encryptedKey = await rsaEncrypt(aesKey, publicKey)
  
  return { encryptedKey, cipherText, iv }
}

async function hybridDecrypt({ encryptedKey, cipherText, iv }, privateKey) {
  // 1. 解密AES密钥
  const aesKey = await rsaDecrypt(encryptedKey, privateKey)
  
  // 2. 解密数据
  return aesDecrypt({ cipherText, iv }, aesKey)
}

六、安全增强措施

  1. 动态密钥管理

    // 每次页面加载从服务端获取密钥
    async function getEncryptionKey() {
      const res = await fetch('/api/encryption-key')
      return res.json().key
    }
    
  2. 内存密钥保护

    const volatileKey = new WeakMap() // 内存中不保留密钥副本
    
    function storeKey(key) {
      const obj = {}
      volatileKey.set(obj, key)
      return obj
    }
    
  3. 加密数据验证

    function encryptWithHMAC(text, key) {
      const cipherText = encrypt(text, key)
      const hmac = CryptoJS.HmacSHA256(cipherText, key).toString()
      return `${hmac}$${cipherText}`
    }
    

七、不同场景选型建议

场景 推荐方案 优点
现代浏览器应用 Web Crypto API + Pinia 原生支持,性能最优
兼容旧浏览器 CryptoJS + Vuex 兼容性好,API简单
高安全要求系统 混合加密 + 服务端密钥管理 防御中间人攻击
临时数据保护 内存加密 + Web Workers 数据不落盘

八、注意事项

  1. 不要加密以下内容

    • 需要服务端处理的原始数据
    • 前端展示的明文信息
    • 高频更新的状态数据
  2. 性能监控

    // 加密性能测试
    console.time('AES加密耗时')
    const encrypted = encrypt(largeData)
    console.timeEnd('AES加密耗时') 
    
  3. 错误处理

    try {
      const data = decrypt(encryptedText)
    } catch (err) {
      Sentry.captureException(err)
      showToast('数据损坏,请重新登录')
    }
    

 

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐