fix
This commit is contained in:
@@ -1,339 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import DetailHeader from '@/components/Layout/DetailHeader/DetailHeader.vue'
|
||||
import ToolDetail from '@/components/Layout/ToolDetail/ToolDetail.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { copy } from '@/utils/string'
|
||||
|
||||
const title = "AES加解密"
|
||||
|
||||
// 状态管理
|
||||
const activeTab = ref('encrypt')
|
||||
const inputText = ref('')
|
||||
const outputText = ref('')
|
||||
const key = ref('')
|
||||
const iv = ref('')
|
||||
const mode = ref('CBC')
|
||||
const keySize = ref(128)
|
||||
|
||||
// 加密模式选项
|
||||
const modeOptions = [
|
||||
{ label: 'CBC', value: 'CBC' },
|
||||
{ label: 'ECB', value: 'ECB' }
|
||||
]
|
||||
|
||||
// 密钥长度选项
|
||||
const keySizeOptions = [
|
||||
{ label: '128位', value: 128 },
|
||||
{ label: '192位', value: 192 },
|
||||
{ label: '256位', value: 256 }
|
||||
]
|
||||
|
||||
// 加密处理
|
||||
const encrypt = async () => {
|
||||
if (!inputText.value) {
|
||||
ElMessage.warning('请输入要加密的文本')
|
||||
return
|
||||
}
|
||||
|
||||
if (!key.value) {
|
||||
ElMessage.warning('请输入密钥')
|
||||
return
|
||||
}
|
||||
|
||||
if (mode.value === 'CBC' && !iv.value) {
|
||||
ElMessage.warning('CBC模式需要输入初始化向量(IV)')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 生成密钥
|
||||
const cryptoKey = await generateKey(key.value, keySize.value)
|
||||
|
||||
// 加密
|
||||
const encrypted = await aesEncrypt(inputText.value, cryptoKey, iv.value, mode.value)
|
||||
outputText.value = btoa(encrypted)
|
||||
|
||||
ElMessage.success('加密成功')
|
||||
} catch (error) {
|
||||
ElMessage.error('加密失败:' + error)
|
||||
}
|
||||
}
|
||||
|
||||
// 解密处理
|
||||
const decrypt = async () => {
|
||||
if (!inputText.value) {
|
||||
ElMessage.warning('请输入要解密的文本')
|
||||
return
|
||||
}
|
||||
|
||||
if (!key.value) {
|
||||
ElMessage.warning('请输入密钥')
|
||||
return
|
||||
}
|
||||
|
||||
if (mode.value === 'CBC' && !iv.value) {
|
||||
ElMessage.warning('CBC模式需要输入初始化向量(IV)')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 生成密钥
|
||||
const cryptoKey = await generateKey(key.value, keySize.value)
|
||||
|
||||
// 解密
|
||||
const decrypted = await aesDecrypt(atob(inputText.value), cryptoKey, iv.value, mode.value)
|
||||
outputText.value = decrypted
|
||||
|
||||
ElMessage.success('解密成功')
|
||||
} catch (error) {
|
||||
ElMessage.error('解密失败:' + error)
|
||||
}
|
||||
}
|
||||
|
||||
// 生成密钥
|
||||
const generateKey = async (keyStr: string, size: number) => {
|
||||
// 使用SHA-256哈希密钥,确保长度正确
|
||||
const encoder = new TextEncoder()
|
||||
const keyData = encoder.encode(keyStr)
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', keyData)
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer))
|
||||
|
||||
// 根据密钥长度截取
|
||||
const keyBytes = size / 8
|
||||
const keyBuffer = new Uint8Array(hashArray.slice(0, keyBytes))
|
||||
|
||||
return await crypto.subtle.importKey(
|
||||
'raw',
|
||||
keyBuffer,
|
||||
{ name: 'AES-' + mode.value },
|
||||
false,
|
||||
['encrypt', 'decrypt']
|
||||
)
|
||||
}
|
||||
|
||||
// AES加密
|
||||
const aesEncrypt = async (text: string, key: CryptoKey, ivStr: string, mode: string) => {
|
||||
const encoder = new TextEncoder()
|
||||
const data = encoder.encode(text)
|
||||
|
||||
let ivBuffer: Uint8Array
|
||||
if (mode === 'CBC') {
|
||||
// 使用SHA-256哈希IV,确保长度为16字节
|
||||
const ivData = encoder.encode(ivStr)
|
||||
const ivHashBuffer = await crypto.subtle.digest('SHA-256', ivData)
|
||||
ivBuffer = new Uint8Array(ivHashBuffer.slice(0, 16))
|
||||
}
|
||||
|
||||
const algorithm: AlgorithmIdentifier = mode === 'CBC'
|
||||
? { name: 'AES-CBC', iv: ivBuffer! } as AesCbcParams
|
||||
: { name: 'AES-ECB' }
|
||||
|
||||
const encrypted = await crypto.subtle.encrypt(algorithm, key, data)
|
||||
return String.fromCharCode(...new Uint8Array(encrypted))
|
||||
}
|
||||
|
||||
// AES解密
|
||||
const aesDecrypt = async (text: string, key: CryptoKey, ivStr: string, mode: string) => {
|
||||
const data = new Uint8Array(text.split('').map(char => char.charCodeAt(0)))
|
||||
|
||||
let ivBuffer: Uint8Array
|
||||
if (mode === 'CBC') {
|
||||
// 使用SHA-256哈希IV,确保长度为16字节
|
||||
const encoder = new TextEncoder()
|
||||
const ivData = encoder.encode(ivStr)
|
||||
const ivHashBuffer = await crypto.subtle.digest('SHA-256', ivData)
|
||||
ivBuffer = new Uint8Array(ivHashBuffer.slice(0, 16))
|
||||
}
|
||||
|
||||
const algorithm: AlgorithmIdentifier = mode === 'CBC'
|
||||
? { name: 'AES-CBC', iv: ivBuffer! } as AesCbcParams
|
||||
: { name: 'AES-ECB' }
|
||||
|
||||
const decrypted = await crypto.subtle.decrypt(algorithm, key, data)
|
||||
const decoder = new TextDecoder()
|
||||
return decoder.decode(decrypted)
|
||||
}
|
||||
|
||||
// 复制结果
|
||||
const copyResult = () => {
|
||||
if (!outputText.value) {
|
||||
ElMessage.warning('没有可复制的内容')
|
||||
return
|
||||
}
|
||||
|
||||
copy(outputText.value)
|
||||
}
|
||||
|
||||
// 清空输入
|
||||
const clearInput = () => {
|
||||
inputText.value = ''
|
||||
outputText.value = ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col mt-3 flex-1">
|
||||
<DetailHeader :title="title"></DetailHeader>
|
||||
|
||||
<div class="p-4 rounded-2xl bg-white">
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tab-pane label="加密" name="encrypt">
|
||||
<!-- 输入部分 -->
|
||||
<div class="mb-4">
|
||||
<el-input
|
||||
v-model="inputText"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入要加密的文本"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<el-input
|
||||
v-model="key"
|
||||
placeholder="请输入密钥"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<el-input
|
||||
v-model="iv"
|
||||
placeholder="请输入初始化向量(IV) (CBC模式必填)"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<div class="flex gap-4 items-center mb-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<el-text>加密模式:</el-text>
|
||||
<el-select v-model="mode" style="width: 120px;">
|
||||
<el-option
|
||||
v-for="option in modeOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<el-text>密钥长度:</el-text>
|
||||
<el-select v-model="keySize" style="width: 120px;">
|
||||
<el-option
|
||||
v-for="option in keySizeOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="mb-4">
|
||||
<el-button type="primary" @click="encrypt">加密</el-button>
|
||||
<el-button @click="clearInput">清空</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 结果部分 -->
|
||||
<div>
|
||||
<el-input
|
||||
v-model="outputText"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="加密结果"
|
||||
readonly
|
||||
>
|
||||
<template #append>
|
||||
<el-button @click="copyResult">复制</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="解密" name="decrypt">
|
||||
<!-- 输入部分 -->
|
||||
<div class="mb-4">
|
||||
<el-input
|
||||
v-model="inputText"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入要解密的文本"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<el-input
|
||||
v-model="key"
|
||||
placeholder="请输入密钥"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<el-input
|
||||
v-model="iv"
|
||||
placeholder="请输入初始化向量(IV) (CBC模式必填)"
|
||||
class="mb-2"
|
||||
/>
|
||||
|
||||
<div class="flex gap-4 items-center mb-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<el-text>加密模式:</el-text>
|
||||
<el-select v-model="mode" class="w-32">
|
||||
<el-option
|
||||
v-for="option in modeOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<el-text>密钥长度:</el-text>
|
||||
<el-select v-model="keySize" class="w-32">
|
||||
<el-option
|
||||
v-for="option in keySizeOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="mb-4">
|
||||
<el-button type="primary" @click="decrypt">解密</el-button>
|
||||
<el-button @click="clearInput">清空</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 结果部分 -->
|
||||
<div>
|
||||
<el-input
|
||||
v-model="outputText"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="解密结果"
|
||||
readonly
|
||||
>
|
||||
<template #append>
|
||||
<el-button @click="copyResult">复制</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<!-- desc -->
|
||||
<ToolDetail title="描述">
|
||||
<el-text>
|
||||
在线AES加解密工具,支持CBC和ECB模式,支持128位、192位、256位密钥长度,可用于数据加密和解密。
|
||||
</el-text>
|
||||
</ToolDetail>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,419 +0,0 @@
|
||||
<template>
|
||||
<div class="flex flex-col mt-3 flex-1">
|
||||
<DetailHeader :title="title"></DetailHeader>
|
||||
|
||||
<div class="p-4 rounded-2xl bg-white">
|
||||
<div class="tool-content">
|
||||
<div class="input-section">
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tab-pane label="加密" name="encrypt">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<el-form label-width="120px">
|
||||
<el-form-item label="输入内容">
|
||||
<el-input
|
||||
v-model="encryptInput"
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
placeholder="请输入待加密的明文"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="密钥">
|
||||
<el-input
|
||||
v-model="encryptKey"
|
||||
type="password"
|
||||
placeholder="请输入密钥"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="加密模式">
|
||||
<el-select v-model="encryptMode" placeholder="请选择加密模式">
|
||||
<el-option label="CBC" value="cbc" />
|
||||
<el-option label="ECB" value="ecb" />
|
||||
<el-option label="CFB" value="cfb" />
|
||||
<el-option label="CTR" value="ctr" />
|
||||
<el-option label="OFB" value="ofb" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="填充方式">
|
||||
<el-select v-model="encryptPadding" placeholder="请选择填充方式">
|
||||
<el-option label="Pkcs7" value="pkcs7" />
|
||||
<el-option label="Iso97971" value="iso97971" />
|
||||
<el-option label="AnsiX923" value="ansix923" />
|
||||
<el-option label="ZeroPadding" value="zeropadding" />
|
||||
<el-option label="NoPadding" value="nopadding" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="初始向量 (IV)" v-if="encryptMode !== 'ecb'">
|
||||
<el-input
|
||||
v-model="encryptIv"
|
||||
placeholder="请输入16位初始向量"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="输出编码">
|
||||
<el-select v-model="encryptOutputEncoding" placeholder="请选择输出编码">
|
||||
<el-option label="Base64" value="base64" />
|
||||
<el-option label="HEX" value="hex" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="encrypt">加密</el-button>
|
||||
<el-button @click="clearEncrypt">清空</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<el-form label-width="120px">
|
||||
<el-form-item label="加密结果">
|
||||
<el-input
|
||||
v-model="encryptOutput"
|
||||
type="textarea"
|
||||
:rows="10"
|
||||
placeholder="加密后的密文将显示在这里"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button @click="copyEncryptResult">复制结果</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="解密" name="decrypt">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<el-form label-width="120px">
|
||||
<el-form-item label="输入内容">
|
||||
<el-input
|
||||
v-model="decryptInput"
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
placeholder="请输入待解密的密文"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="密钥">
|
||||
<el-input
|
||||
v-model="decryptKey"
|
||||
type="password"
|
||||
placeholder="请输入密钥"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="解密模式">
|
||||
<el-select v-model="decryptMode" placeholder="请选择解密模式">
|
||||
<el-option label="CBC" value="cbc" />
|
||||
<el-option label="ECB" value="ecb" />
|
||||
<el-option label="CFB" value="cfb" />
|
||||
<el-option label="CTR" value="ctr" />
|
||||
<el-option label="OFB" value="ofb" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="填充方式">
|
||||
<el-select v-model="decryptPadding" placeholder="请选择填充方式">
|
||||
<el-option label="Pkcs7" value="pkcs7" />
|
||||
<el-option label="Iso97971" value="iso97971" />
|
||||
<el-option label="AnsiX923" value="ansix923" />
|
||||
<el-option label="ZeroPadding" value="zeropadding" />
|
||||
<el-option label="NoPadding" value="nopadding" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="初始向量 (IV)" v-if="decryptMode !== 'ecb'">
|
||||
<el-input
|
||||
v-model="decryptIv"
|
||||
placeholder="请输入16位初始向量"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="输入编码">
|
||||
<el-select v-model="decryptInputEncoding" placeholder="请选择输入编码">
|
||||
<el-option label="Base64" value="base64" />
|
||||
<el-option label="HEX" value="hex" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="decrypt">解密</el-button>
|
||||
<el-button @click="clearDecrypt">清空</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<el-form label-width="120px">
|
||||
<el-form-item label="解密结果">
|
||||
<el-input
|
||||
v-model="decryptOutput"
|
||||
type="textarea"
|
||||
:rows="10"
|
||||
placeholder="解密后的明文将显示在这里"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button @click="copyDecryptResult">复制结果</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- desc -->
|
||||
<ToolDetail title="描述">
|
||||
<el-text>
|
||||
在线AES加密解密工具,支持多种加密模式和填充方式,提供安全可靠的数据加密解密服务。
|
||||
</el-text>
|
||||
</ToolDetail>
|
||||
|
||||
<!-- 安全使用建议 -->
|
||||
<ToolDetail title="安全使用建议">
|
||||
<el-text>
|
||||
<ul>
|
||||
<li>使用强随机数生成器生成密钥和IV</li>
|
||||
<li>推荐使用CBC模式而非ECB模式</li>
|
||||
<li>定期更换密钥和IV</li>
|
||||
<li>妥善保管密钥,不要泄露给他人</li>
|
||||
<li>在生产环境中使用AES-256而非AES-128</li>
|
||||
</ul>
|
||||
</el-text>
|
||||
</ToolDetail>
|
||||
|
||||
<!-- 常见应用场景 -->
|
||||
<ToolDetail title="常见应用场景">
|
||||
<el-text>
|
||||
<ul>
|
||||
<li>数据传输加密:保护网络传输中的敏感数据</li>
|
||||
<li>文件存储加密:加密本地存储的重要文件</li>
|
||||
<li>API通信加密:保护API接口的数据安全</li>
|
||||
</ul>
|
||||
</el-text>
|
||||
</ToolDetail>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import DetailHeader from '@/components/Layout/DetailHeader/DetailHeader.vue'
|
||||
import ToolDetail from '@/components/Layout/ToolDetail/ToolDetail.vue'
|
||||
import CryptoJS from 'crypto-js';
|
||||
|
||||
const title = "AES加密解密"
|
||||
|
||||
const activeTab = ref('encrypt');
|
||||
|
||||
// 加密相关
|
||||
const encryptInput = ref('');
|
||||
const encryptKey = ref('');
|
||||
const encryptMode = ref('cbc');
|
||||
const encryptPadding = ref('pkcs7');
|
||||
const encryptIv = ref('');
|
||||
const encryptOutputEncoding = ref('base64');
|
||||
const encryptOutput = ref('');
|
||||
|
||||
// 解密相关
|
||||
const decryptInput = ref('');
|
||||
const decryptKey = ref('');
|
||||
const decryptMode = ref('cbc');
|
||||
const decryptPadding = ref('pkcs7');
|
||||
const decryptIv = ref('');
|
||||
const decryptInputEncoding = ref('base64');
|
||||
const decryptOutput = ref('');
|
||||
|
||||
// 获取加密模式
|
||||
const getCipherMode = (mode: string) => {
|
||||
switch (mode) {
|
||||
case 'cbc':
|
||||
return CryptoJS.mode.CBC;
|
||||
case 'ecb':
|
||||
return CryptoJS.mode.ECB;
|
||||
case 'cfb':
|
||||
return CryptoJS.mode.CFB;
|
||||
case 'ctr':
|
||||
return CryptoJS.mode.CTR;
|
||||
case 'ofb':
|
||||
return CryptoJS.mode.OFB;
|
||||
default:
|
||||
return CryptoJS.mode.CBC;
|
||||
}
|
||||
};
|
||||
|
||||
// 获取填充方式
|
||||
const getPadding = (padding: string) => {
|
||||
switch (padding) {
|
||||
case 'pkcs7':
|
||||
return CryptoJS.pad.Pkcs7;
|
||||
case 'iso97971':
|
||||
return CryptoJS.pad.Iso97971;
|
||||
case 'ansix923':
|
||||
return CryptoJS.pad.AnsiX923;
|
||||
case 'zeropadding':
|
||||
return CryptoJS.pad.ZeroPadding;
|
||||
case 'nopadding':
|
||||
return CryptoJS.pad.NoPadding;
|
||||
default:
|
||||
return CryptoJS.pad.Pkcs7;
|
||||
}
|
||||
};
|
||||
|
||||
// 加密函数
|
||||
const encrypt = () => {
|
||||
if (!encryptInput.value) {
|
||||
ElMessage.warning('请输入待加密的明文');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!encryptKey.value) {
|
||||
ElMessage.warning('请输入密钥');
|
||||
return;
|
||||
}
|
||||
|
||||
if (encryptMode.value !== 'ecb' && !encryptIv.value) {
|
||||
ElMessage.warning('请输入初始向量 (IV)');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const key = CryptoJS.enc.Utf8.parse(encryptKey.value);
|
||||
const iv = encryptMode.value !== 'ecb' ? CryptoJS.enc.Utf8.parse(encryptIv.value) : undefined;
|
||||
const mode = getCipherMode(encryptMode.value);
|
||||
const padding = getPadding(encryptPadding.value);
|
||||
|
||||
const cipher = CryptoJS.AES.encrypt(encryptInput.value, key, {
|
||||
iv: iv,
|
||||
mode: mode,
|
||||
padding: padding
|
||||
});
|
||||
|
||||
if (encryptOutputEncoding.value === 'base64') {
|
||||
encryptOutput.value = cipher.toString();
|
||||
} else {
|
||||
encryptOutput.value = cipher.ciphertext.toString(CryptoJS.enc.Hex);
|
||||
}
|
||||
|
||||
ElMessage.success('加密成功');
|
||||
} catch (error) {
|
||||
ElMessage.error('加密失败:' + (error as Error).message);
|
||||
}
|
||||
};
|
||||
|
||||
// 解密函数
|
||||
const decrypt = () => {
|
||||
if (!decryptInput.value) {
|
||||
ElMessage.warning('请输入待解密的密文');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!decryptKey.value) {
|
||||
ElMessage.warning('请输入密钥');
|
||||
return;
|
||||
}
|
||||
|
||||
if (decryptMode.value !== 'ecb' && !decryptIv.value) {
|
||||
ElMessage.warning('请输入初始向量 (IV)');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const key = CryptoJS.enc.Utf8.parse(decryptKey.value);
|
||||
const iv = decryptMode.value !== 'ecb' ? CryptoJS.enc.Utf8.parse(decryptIv.value) : undefined;
|
||||
const mode = getCipherMode(decryptMode.value);
|
||||
const padding = getPadding(decryptPadding.value);
|
||||
|
||||
let ciphertext;
|
||||
if (decryptInputEncoding.value === 'base64') {
|
||||
ciphertext = decryptInput.value;
|
||||
} else {
|
||||
ciphertext = CryptoJS.enc.Hex.parse(decryptInput.value);
|
||||
}
|
||||
|
||||
const decrypted = CryptoJS.AES.decrypt(ciphertext, key, {
|
||||
iv: iv,
|
||||
mode: mode,
|
||||
padding: padding
|
||||
});
|
||||
|
||||
decryptOutput.value = decrypted.toString(CryptoJS.enc.Utf8);
|
||||
ElMessage.success('解密成功');
|
||||
} catch (error) {
|
||||
ElMessage.error('解密失败:' + (error as Error).message);
|
||||
}
|
||||
};
|
||||
|
||||
// 清空加密
|
||||
const clearEncrypt = () => {
|
||||
encryptInput.value = '';
|
||||
encryptKey.value = '';
|
||||
encryptIv.value = '';
|
||||
encryptOutput.value = '';
|
||||
};
|
||||
|
||||
// 清空解密
|
||||
const clearDecrypt = () => {
|
||||
decryptInput.value = '';
|
||||
decryptKey.value = '';
|
||||
decryptIv.value = '';
|
||||
decryptOutput.value = '';
|
||||
};
|
||||
|
||||
// 复制加密结果
|
||||
const copyEncryptResult = () => {
|
||||
if (!encryptOutput.value) {
|
||||
ElMessage.warning('没有可复制的内容');
|
||||
return;
|
||||
}
|
||||
|
||||
navigator.clipboard.writeText(encryptOutput.value).then(() => {
|
||||
ElMessage.success('已复制加密结果');
|
||||
}).catch(() => {
|
||||
ElMessage.error('复制失败');
|
||||
});
|
||||
};
|
||||
|
||||
// 复制解密结果
|
||||
const copyDecryptResult = () => {
|
||||
if (!decryptOutput.value) {
|
||||
ElMessage.warning('没有可复制的内容');
|
||||
return;
|
||||
}
|
||||
|
||||
navigator.clipboard.writeText(decryptOutput.value).then(() => {
|
||||
ElMessage.success('已复制解密结果');
|
||||
}).catch(() => {
|
||||
ElMessage.error('复制失败');
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tool-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.input-section {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.grid-cols-1.md\:grid-cols-2 {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -161,15 +161,7 @@ export function getToolsCate() {
|
||||
cateId: 2,
|
||||
cate: '开发运维',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
title: 'AES加解密',
|
||||
logo: '/images/logo/md5.png',
|
||||
desc: '在线AES加解密工具,支持多种加密模式和填充方式,提供安全可靠的数据加密解密服务',
|
||||
url: '/aes/',
|
||||
cateId: 2,
|
||||
cate: '开发运维',
|
||||
},
|
||||
|
||||
{
|
||||
id: 1,
|
||||
title: 'Hash计算器',
|
||||
@@ -179,15 +171,6 @@ export function getToolsCate() {
|
||||
cateId: 2,
|
||||
cate: '开发运维',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
title: 'SHA1加解密',
|
||||
logo: '/images/logo/sha1.svg',
|
||||
desc: '在线SHA1哈希计算器,用于计算文本的SHA1哈希值',
|
||||
url: '/sha1/',
|
||||
cateId: 2,
|
||||
cate: '开发运维',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
title: 'XML格式化',
|
||||
|
||||
Reference in New Issue
Block a user