前景
由于公司的项目用到了国密加密,而且又是使用内网开发,导致接口开发后返回的数据为加密后的值,返回参数必须复制出来,然后调用根据类去解密参数,而且解密后的参数没有格式化也不美观,就琢磨着为什么不自己写一个工具,复制值进去就自动解析解放生产力
开始开发
清单文件(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
的父文件夹)
然后我们就可以愉快的使用我们的插件了