前景
由于公司的项目用到了国密加密,而且又是使用内网开发,导致接口开发后返回的数据为加密后的值,返回参数必须复制出来,然后调用根据类去解密参数,而且解密后的参数没有格式化也不美观,就琢磨着为什么不自己写一个工具,复制值进去就自动解析解放生产力
开始开发
清单文件(manifest.json)
首先在插件根目录插件一个清单文件 manifest.json
            
            
              json
              
              
            
          
          {
  "manifest_version": 3,
  "name": "国密解密",
  "version": "1.0",
  "description": "对国密内容进行解密",
  "action": {
    "default_icon": {
      "16": "icon16.png",
      "48": "icon48.png",
      "128": "icon128.png"
    },
    "default_title": "跳转插件页面"
  },
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["tabs"]
}
        manifest_version用于指定扩展程序使用的清单文件格式版本,固定写3即可name插件名称action.default_icon插件图标action.default_title鼠标hover的时候提示的文案background.service_worker控制的js文件,插件安装成功执行background.js中的代码
background.js
在 manifest.json 同级创建background.js文件
            
            
              JavaScript
              
              
            
          
          chrome.action.onClicked.addListener(() => {
    // 使用 chrome.runtime.getURL 获取插件内部页面的URL
    const internalPageUrl = chrome.runtime.getURL("./src/index.html");
    // 在新标签页中打开插件页面
    chrome.tabs.create({ url: internalPageUrl });
});
        监听点击插件后,去根据相对路径去得到绝对地址并打开地址
./src/index.html这就是我们的打包后的产物
开始我们愉快的开发
 首先检查我们的 manifest.json 和 background.js 以及 src 目录的创建
然后我们创建一个正常的vue3项目
 主要就用到四个包
- element-plus 负责界面的表单内容
 - jsoneditor 格式化我们解密后的内容,美观输出到界面,方便查看
 - sm-crypto 加密/解密的包,我们会使用到其中的 
sm4 - @types/sm-crypto 为
sm-crypto增加语法提示 
解密部分代码
            
            
              html
              
              
            
          
          <script setup lang="ts">
import {onMounted, ref} from "vue";
// @ts-ignore
import JSONEditor from 'jsoneditor'
import 'jsoneditor/dist/jsoneditor.min.css'
import 'jsoneditor/dist/jsoneditor.min.js'
import {ElMessage} from "element-plus";
import { sm4 } from "sm-crypto"
const key = ref('')
const iv = ref('')
const padding = ref<'pkcs#7'|'pkcs#5'>('pkcs#7')
const signText = ref('')
const jsonEditor = ref()
const editor = ref<any>()
const onSubmit = () => {
  if(!signText.value) return ElMessage.error('请输入待解密的数据')
  if(!key.value) return ElMessage.error('请输入key')
  if(!iv.value) return ElMessage.error('请输入iv')
  try {
    const data = sm4.decrypt(signText.value, key.value, { iv: iv.value, mode: 'cbc', padding: padding.value })
    if(data == '') throw new Error('解密内容失败,请检查是否为正确的加密内容')
    console.log(data)
    editor.value.set(data)
  } catch (e: any) {
    ElMessage.error(e.message)
  }
}
onMounted(() => {
  editor.value = new JSONEditor(jsonEditor.value, { mode: 'code' }, "");
  const localKey = localStorage.getItem('sm4_key')
  const localIv = localStorage.getItem('sm4_iv')
  const localPadding = localStorage.getItem('sm4_padding')
  if(localKey) key.value = localKey
  if(localIv) iv.value = localIv
  if(localPadding) padding.value = localPadding as any
  window.addEventListener('beforeunload', () => {
    if(key.value) localStorage.setItem('sm4_key', key.value)
    if(iv.value) localStorage.setItem('sm4_iv', iv.value)
    if(padding.value) localStorage.setItem('sm4_padding', padding.value)
  })
})
</script>
<template>
  <div class="page">
    <div style="flex: 1; overflow: hidden;border: solid 1px #ddd; padding: 20px; box-sizing: border-box;">
      <el-form label-width="auto" style="width: 100%">
        <el-form-item label="key">
          <el-input v-model="key" placeholder="请输入key" />
        </el-form-item>
        <el-form-item label="iv">
          <el-input v-model="iv" placeholder="请输入iv" />
        </el-form-item>
        <el-form-item label="填充模式">
          <el-select v-model="padding" placeholder="请选择填充模式">
            <el-option key="pkcs#7" label="pkcs#7" value="pkcs#7" />
            <el-option key="pkcs#5" label="pkcs#5" value="pkcs#5" />
          </el-select>
        </el-form-item>
        <el-form-item label="加密内容">
          <el-input v-model="signText" placeholder="请输入加密内容" type="textarea" :autosize="{ minRows: 4, maxRows: 8 }" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">解密</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div style="width: 60%; overflow: hidden;border: solid 1px #ddd; margin-left: 10px;">
      <div ref="jsonEditor" class="target" style="height: 95vh"></div>
    </div>
  </div>
</template>
<style scoped>
.page {
  width: 100vw;
  height: 100vh;
  display: flex;
}
.read-the-docs {
  color: #888;
}
</style>
        打包安装插件
首先我们运行一遍pnpm run build打包一下完成后的开发界面 要注意:默认打包后的路径为绝对路径,可以通过vite.config.ts去修改打包为相对路径,在这里为了省事我们直接改为相对路径即可。
打包后将打包产物移到src中
我们的结构应如图所示
然后我们打开链接chrome://extensions/,进入后我们打开开发者模式,加载已解压程序,直接选择我们的开发根目录对应的文件夹即可(manifest.json的父文件夹)
然后我们就可以愉快的使用我们的插件了