Created
March 23, 2023 10:49
-
-
Save hongchaodeng/930423cece612d6050c76c8f54af6bcf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Below is the code for SM4 Encryption tool: | |
``` | |
<template> | |
<h-text-transform | |
ref="cryptRef" | |
enableFile | |
:fileOutputAlert="t('enc')" | |
:sampleData="sample" | |
:transform="encrypt" | |
:fileOutputName="fileName"> | |
<template #option> | |
<a-space style="margin-top: 16px"> | |
<span> | |
<a-radio-group | |
option-type="button" | |
:options="formatOptions" | |
@change="SynchronizeInput(passwordType)" | |
v-model:value="passwordType" /> | |
</span> | |
<span>{{ t('key') }}</span> | |
<a-input-password v-model:value="keyString" @change="callCryptMethod" /> | |
<span>{{ t('mode') }}</span> | |
<span> | |
<a-select v-model:value="cipherType" @change="callCryptMethod"> | |
<a-select-option :value="SM4Type.CBC"> | |
{{ SM4Type.CBC }} | |
</a-select-option> | |
<a-select-option :value="SM4Type.ECB"> | |
{{ SM4Type.ECB }} | |
</a-select-option> | |
</a-select> | |
</span> | |
<span>{{ t('outputType') }}:</span> | |
<span> | |
<a-select v-model:value="outputType" @change="callCryptMethod"> | |
<a-select-option :value="OutputType.Base64"> | |
{{ OutputType.Base64 }} | |
</a-select-option> | |
<a-select-option :value="OutputType.Hex"> | |
{{ OutputType.Hex }} | |
</a-select-option> | |
</a-select> | |
</span> | |
</a-space> | |
</template> | |
</h-text-transform> | |
</template> | |
<script setup lang="ts"> | |
import { SM4 } from 'gm-crypto'; | |
import { Buffer } from 'buffer'; | |
import utf8 from 'utf8'; | |
import { ref } from 'vue'; | |
import { useI18n } from 'vue-i18n'; | |
import messages from './lang.json'; | |
const { t } = useI18n({ | |
locale: window.$he3.lang, | |
messages, | |
}); | |
enum SM4Type { | |
ECB = 'ECB', | |
CBC = 'CBC', | |
} | |
enum OutputType { | |
Utf8 = 'utf8', | |
Base64 = 'base64', | |
Hex = 'hex', | |
} | |
const formatOptions = [ | |
{ label: 'Hex', value: 'hex' }, | |
{ label: 'Base64', value: 'base64' }, | |
{ label: 'Utf8', value: 'utf8' }, | |
]; | |
const inputType = ref(OutputType.Utf8) | |
const passwordType = ref<OutputType>(OutputType.Hex) | |
const outputType = ref(OutputType.Base64) | |
const sample = 'A Free, Modern Toolbox, Built for Developers.' | |
const keyString = ref('0123456789abcdeffedcba9876543210') //绑定input的key,非最后用于加密的 | |
const realKey = ref('0123456789abcdeffedcba9876543210') //用于SM4.encrypt加密的key | |
const cipherType = ref(SM4Type.ECB); | |
const cryptRef = ref(); | |
const callCryptMethod = () => { | |
cryptRef.value.handleChange(); | |
}; | |
//base64转hex | |
function convert(str: string): string { | |
let buf = Buffer.from(str, 'base64'); | |
return buf.toString('hex'); | |
} | |
//string转hex | |
const stringToHex = (str: string) => { | |
let result = utf8.encode(str); | |
let ret = ''; | |
for (let n = 0; n < result.length; n++) { | |
let t = result[n].charCodeAt(0).toString(16).toUpperCase(); | |
ret += t; | |
} | |
return ret; | |
}; | |
//切换密钥类型的响应事件 | |
const SynchronizeInput = (btnType: string) => { | |
switch (btnType) { | |
case OutputType.Hex: | |
keyString.value = '0123456789abcdeffedcba9876543210' | |
break | |
case OutputType.Base64: | |
keyString.value = 'ASNFZ4mrze/+3LqYdlQyEA==' | |
break | |
case OutputType.Utf8: | |
keyString.value = '示例字符串A' | |
break | |
} | |
callCryptMethod() | |
} | |
const encrypt = (rawValue: string) => { | |
judgeLength(rawValue, keyString); | |
let cipherOps = { | |
mode: SM4.constants.CBC, | |
}; | |
switch (cipherType.value) { | |
case SM4Type.ECB: | |
cipherOps.mode = SM4.constants.ECB; | |
break; | |
case SM4Type.CBC: | |
cipherOps.mode = SM4.constants.CBC; | |
break; | |
} | |
switch (passwordType.value) { | |
case OutputType.Hex: | |
realKey.value = keyString.value; | |
break; | |
case OutputType.Base64: | |
realKey.value = convert(keyString.value); | |
break; | |
case OutputType.Utf8: | |
realKey.value = stringToHex(keyString.value); | |
break; | |
} | |
try { | |
const ripeValue = SM4.encrypt(rawValue, realKey.value, { | |
iv: realKey.value, | |
mode: cipherOps.mode, | |
inputEncoding: inputType.value, | |
outputEncoding: outputType.value, | |
}); | |
return ripeValue; | |
} catch (error) { | |
window.$he3.message.error(error.message); | |
return ''; | |
} | |
}; | |
/** 返回函数名,加密文件添加enc后缀 */ | |
const fileName = (fileName: string) => { | |
return fileName + '.enc'; | |
}; | |
const judgeLength = (rawVal: string, keyVal: any) => { | |
if (rawVal.length <= 0) { | |
window.$he3.message.warn('Please enter the plain text'); | |
return ''; | |
} | |
if (keyVal.value.length <= 0) { | |
window.$he3.message.warn('Please enter the key'); | |
return ''; | |
} | |
}; | |
</script> | |
``` | |
It has the following input options: | |
- It has two options to input raw text: text input box or document file upload since its`h-text-transform` component has the `enableFile` attribute. Otherwise, it will only have text input box. | |
- It has three options for passphrase type: Hex, Base64, Utf8. | |
- It has an input box for passphrase. | |
- It has two cipher modes: CBC, ECB. | |
- It has three options for output type: Hex, Base64, Utf8. | |
Below is the code for Base64 To Hex tool: | |
``` | |
<template> | |
<h-text-transform | |
ref="transformRef" | |
:sampleData="EXAMPLE_BASE64_STRING" | |
:transform="transform" | |
> | |
<template #option> | |
<div class="option"> | |
<span class="result-opt"> | |
<span class="opt">{{ t('delimiter_tip') }}</span> | |
<span class="opt"> | |
<a-select | |
v-model:value="delimiter" | |
size="small" | |
@change="handleChange" | |
> | |
<a-select-option :value="''"> | |
({{ t('delimiter_empty') }}) | |
</a-select-option> | |
<a-select-option :value="':'"> | |
{{ t('delimiter_colon') }}(:) | |
</a-select-option> | |
<a-select-option :value="' '"> | |
{{ t('delimiter_space') }}({{ ' ' }}) | |
</a-select-option> | |
<a-select-option :value="'-'"> | |
{{ t('delimiter_hyphen') }}(-) | |
</a-select-option> | |
</a-select> | |
</span> | |
<span class="opt"> | |
<a-radio-group | |
v-model:value="resultCase" | |
size="small" | |
@change="handleChange" | |
> | |
<a-radio-button value="lower"> | |
{{ t('lower_case') }} | |
</a-radio-button> | |
<a-radio-button value="upper"> | |
{{ t('upper_case') }} | |
</a-radio-button> | |
</a-radio-group> | |
</span> | |
</span> | |
</div> | |
</template> | |
</h-text-transform> | |
</template> | |
<script setup lang="ts"> | |
import { Buffer } from 'buffer'; | |
import { ref } from 'vue'; | |
import { useI18n } from 'vue-i18n'; | |
import messages from './lang.json'; | |
const { t } = useI18n({ | |
locale: window.$he3.lang, | |
messages, | |
}); | |
const EXAMPLE_BASE64_STRING = | |
'H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO'; | |
const delimiter = ref(''); | |
const resultCase = ref('lower'); | |
const transformRef = ref(); | |
const handleChange = () => { | |
transformRef.value.handleChange(); | |
}; | |
function transform(inputValue: string) { | |
let res = Buffer.from(inputValue, 'base64').toString('hex'); | |
if (delimiter.value != '' && res.length > 2) { | |
const arr = []; | |
for (let index = 0; index < res.length; index += 2) { | |
arr.push(res.slice(index, index + 2)); | |
} | |
res = arr.join(delimiter.value); | |
} | |
if (resultCase.value === 'upper') res = res.toUpperCase(); | |
return res; | |
} | |
</script> | |
<style scoped lang="less"> | |
.option { | |
margin: 20px 0px; | |
height: 30px; | |
.result-opt { | |
float: right; | |
.opt { | |
margin-left: 10px; | |
} | |
} | |
} | |
</style> | |
``` | |
It has the following input options: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment