Vue3安全新防线:RSA加密密码的实现与优化指南

引言

在数据安全日益受到重视的今天,前端加密技术已成为保护用户敏感信息(如密码、身份证号)的"最后防线"。本文将系统解析如何在Vue3项目中通过扩展JSEncrypt库实现RSA长文本加密,并结合TypeScript构建类型安全的加密工具类,同时提供完整的代码实现与实战建议。


一、环境准备与库引入

1. 安装依赖

bash 复制代码
npm install jsencrypt --save
npm install typescript @types/jsencrypt --save-dev

2. 全局引入(推荐)

typescript 复制代码
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import JSEncrypt from 'jsencrypt'

const app = createApp(App)
app.config.globalProperties.$encrypt = new JSEncrypt()
app.mount('#app')

二、核心加密方法解析

1. 分段加密原理

RSA加密存在117字节长度限制(PKCS#1 v1.5填充模式),超过限制需分段处理。通过计算字符编码长度动态截取字符串,确保每段加密后总长度不超过限制。

typescript 复制代码
// 分段加密实现
JSEncrypt.prototype.encryptLong = function (str: string): string | boolean {
  const key = this.getKey()
  let ct = ''
  const bytes = []
  let byteNo = 0

  // 计算分段点
  for (let i = 0; i < str.length; i++) {
    const c = str.charCodeAt(i)
    if (c >= 0x010000) byteNo += 4
    else if (c >= 0x000800) byteNo += 3
    else if (c >= 0x000080) byteNo += 2
    else byteNo += 1

    if ((byteNo % 117) >= 114 || byteNo === 0) {
      bytes.push(i)
      byteNo = 0
    }
  }

  // 分段加密
  for (let i = 0; i < bytes.length - 1; i++) {
    const start = bytes[i] + 1
    const end = bytes[i + 1] + 1
    ct += key.encrypt(str.substring(start, end))
  }

  // 处理最后一段
  if (bytes[bytes.length - 1] !== str.length - 1) {
    ct += key.encrypt(str.substring(bytes[bytes.length - 1] + 1))
  }

  return bytesToHex(ct)
}

三、工具类封装方案

1. 类型安全工具类

typescript 复制代码
// src/utils/rsa.ts
import { JSEncrypt } from 'jsencrypt'

export class RSAUtil {
  private encryptor: JSEncrypt

  constructor() {
    this.encryptor = new JSEncrypt()
  }

  /**
   * 加密密码(自动处理分段)
   * @param password 明文密码
   * @param publicKey 公钥
   */
  encrypt(password: string, publicKey: string): string {
    this.encryptor.setPublicKey(publicKey)
    const encrypted = this.encryptor.encryptLong(password)
    return arrayBufferToBase64(encrypted)
  }

  /**
   * 解密密码(自动处理分段)
   * @param encrypted 密文
   * @param privateKey 私钥
   */
  decrypt(encrypted: string, privateKey: string): string | null {
    this.encryptor.setPrivateKey(privateKey)
    const decrypted = this.encryptor.decryptLong(base64ToArrayBuffer(encrypted))
    return decrypted?.replace(/\+/g, ' ')
  }
}

四、实战使用示例

vue 复制代码
<template>
  <div>
    <input v-model="password" placeholder="输入密码" type="password">
    <button @click="handleEncrypt">加密</button>
    <p>加密结果:{{ encryptedPassword }}</p>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import RSAUtil from '@/utils/rsa'

const password = ref('')
const encryptedPassword = ref('')
const rsaUtil = new RSAUtil()

const handleEncrypt = () => {
  const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H
4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t
0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4
ehde/zUxo6UvS7UrBQIDAQAB-----END PUBLIC KEY-----`
  encryptedPassword.value = rsaUtil.encrypt(password.value, publicKey)
}
</script>

五、性能优化建议

  1. 缓存密钥实例:避免重复创建JSEncrypt对象,建议使用单例模式
  2. 批量加密处理:合并多次加密请求为单次链式调用
  3. Web Worker加速:将加密操作移出主线程处理

六、注意事项

  1. 密钥管理:私钥必须严格保密,公钥可前端存储但需定期轮换
  2. 编码规范:加密前统一使用UTF-8编码,解密后处理Base64转码
  3. 错误处理:添加try-catch捕获异常,避免页面崩溃
相关推荐
Bug收容所4 分钟前
Vue+js Day2
前端·javascript·vue.js
长不大的杨瑞杰4 分钟前
给 OpenCode v2 接入大模型:Provider、模型选择与 API Key 安全配置实战
人工智能·安全·ai·语言模型
掘金酱42 分钟前
带着作品来,坐下来聊|掘金 X-lab · Coffee Talk 邀请你来见一面
前端·javascript·后端
ONLYOFFICE1 小时前
ONLYOFFICE 10.0:深入了解最新的 40 项安全修复
网络·安全
刘婉晴1 小时前
【K8S安全】4. 节点到云
安全·容器·kubernetes
域智盾软件分享1 小时前
一套可落地的终端加密与审计方案:从需求拆解到策略配置
安全·电脑·域智盾
CoovallyAIHub1 小时前
用 AI 做 PPT 被辞退,法院判公司赔:员工贴进对话框的数据,到底谁负责?
前端·agent
fruge2 小时前
SSH、RDP、VNC不必各开一个客户端:Next Terminal用Web入口统一管理远程资产和会话记录
运维·前端·ssh
honkun62 小时前
vue 下拉树组件 vxe-table-select 实现分页多选
前端·javascript·vue.js
企业解惑小能手-域智盾系统2 小时前
终端安全管理软件怎么选?终端安全管理不是“装个客户端”:从底层逻辑看企业怎么选
服务器·网络·安全·域智盾软件