From c8479373eef83c172c7cd4a7c3519e51f590a7d8 Mon Sep 17 00:00:00 2001 From: fofolee Date: Mon, 30 Dec 2024 21:11:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=93=88=E5=B8=8C=E5=92=8C?= =?UTF-8?q?=E7=BC=96=E8=A7=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/lib/RSAEncryption.js | 150 --------- plugin/lib/ShangmiEncryption.js | 149 --------- plugin/lib/SymmetricEncryption.js | 280 ----------------- plugin/lib/quickcomposer/textProcessing.js | 288 ++++++++---------- .../editor/composer/ComposerCard.vue | 4 + .../editor/composer/FunctionSelector.vue | 101 ++++++ .../commands/textProcessingCommands.js | 192 ++++-------- 7 files changed, 292 insertions(+), 872 deletions(-) delete mode 100644 plugin/lib/RSAEncryption.js delete mode 100644 plugin/lib/ShangmiEncryption.js delete mode 100644 plugin/lib/SymmetricEncryption.js create mode 100644 src/components/editor/composer/FunctionSelector.vue diff --git a/plugin/lib/RSAEncryption.js b/plugin/lib/RSAEncryption.js deleted file mode 100644 index 31ff949..0000000 --- a/plugin/lib/RSAEncryption.js +++ /dev/null @@ -1,150 +0,0 @@ -import NodeForge from "node-forge"; -import { forgeBytesToStr, strToForgeBytes, dataConv } from "@/script/Common.js"; - -const RSAPadDict = { - "PKCS#1": { - getMaxSize: (keySize) => Math.floor((keySize - 1) / 8) - 11, - coding: (chunks, secretKey, method) => - secretKey[method](chunks, "RSAES-PKCS1-V1_5"), - }, - OAEP: { - getMaxSize: (keySize) => Math.floor(keySize / 8) - 42, - coding: (chunks, secretKey, method) => - secretKey[method](chunks, "RSA-OAEP"), - }, - "OAEP/SHA-256": { - getMaxSize: (keySize) => Math.floor(keySize / 8) - 66, - coding: (chunks, secretKey, method) => - secretKey[method](chunks, "RSA-OAEP", { - md: NodeForge.md.sha256.create(), - }), - }, - "OAEP/SHA-256/MGF1-SHA-1": { - getMaxSize: (keySize) => Math.floor(keySize / 8) - 74, - coding: (chunks, secretKey, method) => - secretKey[method](chunks, "RSA-OAEP", { - md: NodeForge.md.sha256.create(), - mgf1: { - md: NodeForge.md.sha1.create(), - }, - }), - }, -}; - -const forgeRSAEncrypt = (bytes, padding, publicKey, outputCodec) => { - publicKey = NodeForge.pki.publicKeyFromPem(publicKey); - let keySize = publicKey.n.bitLength(); - let chunks = ""; - let encrypted = ""; - let maxBlockSize = RSAPadDict[padding].getMaxSize(keySize); - for (let i = 0; i < bytes.length / maxBlockSize; i++) { - chunks = bytes.substring(i * maxBlockSize, (i + 1) * maxBlockSize); - chunks = RSAPadDict[padding].coding(chunks, publicKey, "encrypt"); - encrypted += chunks; - } - return outputCodec === "Base64" - ? NodeForge.util.encode64(encrypted) - : NodeForge.util.bytesToHex(encrypted); -}; - -const forgeRSADecrypt = (cipher, padding, privateKey, inputCodec) => { - let bytes = - inputCodec === "Base64" - ? NodeForge.util.decode64(cipher) - : NodeForge.util.hexToBytes(cipher); - privateKey = NodeForge.pki.privateKeyFromPem(privateKey); - let keySize = privateKey.n.bitLength(); - let maxBlockSize = keySize / 8; - let decrypted = ""; - let chunks = ""; - for (let i = 0; i < bytes.length / maxBlockSize; i++) { - chunks = bytes.substring(i * maxBlockSize, (i + 1) * maxBlockSize); - chunks = RSAPadDict[padding].coding(chunks, privateKey, "decrypt"); - decrypted += chunks; - } - return decrypted; -}; - -export const RSA = { - name: "RSA", - params: [ - { - type: "list", - options: ["PKCS#1", "OAEP", "OAEP/SHA-256", "OAEP/SHA-256/MGF1-SHA-1"], - value: "PKCS#1", - }, - { - type: "text", - name: "公钥", - value: ["", "Pem"], - options: ["Pem", "Hex", "Base64"], - id: "publicKey", - }, - { - type: "text", - name: "私钥", - value: ["", "Pem"], - options: ["Pem", "Hex", "Base64"], - id: "privateKey", - }, - { - type: "list", - options: ["Hex", "Base64"], - value: "Base64", - }, - ], - actions: [ - { - type: "action", - name: "生成密钥", - component: "GenerateKeypair", - }, - { - type: "action", - name: "CTF", - component: "RsaCtf", - }, - ], - encrypt: ( - msg, - padding = "PKCS#1", - [pubKey = "", pubKeyCodec = "Pem"], - // eslint-disable-next-line no-unused-vars - [priKey = "", priKeyCodec = "Pem"], - outputCodec = "Base64", - { inputCodec } - ) => { - if (!pubKey) throw "缺少公钥"; - if (pubKeyCodec !== "Pem") { - pubKey = - "-----BEGIN PUBLIC KEY-----\n" + - dataConv(pubKey, pubKeyCodec, "Base64") + - "\n-----END PUBLIC KEY-----"; - } - pubKey = pubKey.replace(/\\n/g, "\n"); - let bytes = strToForgeBytes(msg, inputCodec); - let cipher = forgeRSAEncrypt(bytes, padding, pubKey, outputCodec); - if (!cipher) throw "加密失败"; - return cipher; - }, - decrypt: ( - cipher, - padding = "PKCS#1", - // eslint-disable-next-line no-unused-vars - [pubKey = "", pubKeyCodec = "Pem"], - [priKey = "", priKeyCodec = "Pem"], - codec = "Base64" - ) => { - if (!priKey) return "缺少私钥"; - if (priKeyCodec !== "Pem") { - priKey = - "-----BEGIN PRIVATE KEY-----\n" + - dataConv(priKey, priKeyCodec, "Base64") + - "\n-----END PRIVATE KEY-----"; - } - priKey = priKey.replace(/\\n/g, "\n"); - let msg = forgeRSADecrypt(cipher, padding, priKey, codec); - if (!msg) throw "解密失败"; - return forgeBytesToStr(msg); - }, -}; diff --git a/plugin/lib/ShangmiEncryption.js b/plugin/lib/ShangmiEncryption.js deleted file mode 100644 index 42f4a9f..0000000 --- a/plugin/lib/ShangmiEncryption.js +++ /dev/null @@ -1,149 +0,0 @@ -import { strToBytesArray, bytesArrayToStr, dataConv } from "@/script/Common.js"; -import { processSecret } from "./SymmetricEncryption.js"; -import SM from "sm-crypto"; - -export const SM4 = { - name: "SM4", - params: [ - { - type: "text", - name: "Key", - value: ["", "Utf8"], - options: ["Utf8", "Hex", "Base64"], - }, - { - type: "text", - name: "IV", - value: ["", "Utf8"], - options: ["Utf8", "Hex", "Base64"], - id: "IV", - }, - { - type: "list", - options: ["ECB", "CBC"], - value: "ECB", - banList: { - ECB: ["IV"], - }, - id: "mode", - }, - { type: "list", options: ["pkcs#7", "none"], value: "pkcs#7" }, - { type: "list", options: ["Base64", "Hex"], value: "Base64" }, - ], - encrypt: ( - msg, - key, - iv = "", - mode = "ECB", - padding = "pkcs#7", - outputCodec = "Base64", - { inputCodec } - ) => { - let bytesArray = strToBytesArray(msg, inputCodec); - return dataConv( - SM.sm4.encrypt(bytesArray, processSecret(key, 16, "hex"), { - mode: mode.toLowerCase(), - iv: processSecret(iv, 16, "hex"), - padding: padding, - }), - "Hex", - outputCodec - ); - }, - decrypt: ( - cipher, - key, - iv = "", - mode = "ECB", - padding = "pkcs#7", - codec = "Base64" - ) => { - let bytesArray = SM.sm4.decrypt( - dataConv(cipher, codec, "Hex"), - processSecret(key, 16, "hex"), - { - mode: mode.toLowerCase(), - iv: processSecret(iv, 16, "hex"), - padding: padding, - output: "array", - } - ); - return bytesArrayToStr(bytesArray); - }, -}; - -export const SM2 = { - name: "SM2", - params: [ - { - type: "text", - name: "公钥", - value: ["", "Base64"], - options: ["Hex", "Base64"], - id: "publicKey", - }, - { - type: "text", - name: "私钥", - value: ["", "Base64"], - options: ["Hex", "Base64"], - id: "privateKey", - }, - { - type: "list", - options: [ - { label: "C1C3C2", value: 1 }, - { label: "C1C2C3", value: 0 }, - ], - value: 1, - }, - { - type: "list", - options: ["Hex", "Base64"], - value: "Base64", - }, - ], - actions: [ - { - type: "action", - name: "生成密钥", - component: "GenerateKeypair", - }, - ], - encrypt: ( - msg, - [pubKey = "", pubKeyCodec = "Base64"], - // eslint-disable-next-line no-unused-vars - [priKey = "", priKeyCodec = "Base64"], - cipherMode = 1, - outputCodec = "Base64", - { inputCodec } - ) => { - if (!pubKey) throw "缺少公钥"; - pubKey = dataConv(pubKey, pubKeyCodec, "Hex"); - let cipher = SM.sm2.doEncrypt( - strToBytesArray(msg, inputCodec), - pubKey, - cipherMode - ); - if (!cipher) throw "加密失败"; - return dataConv(cipher, "Hex", outputCodec); - }, - decrypt: ( - cipher, - // eslint-disable-next-line no-unused-vars - [pubKey = "", pubKeyCodec = "Base64"], - [priKey = "", priKeyCodec = "Base64"], - cipherMode = 1, - codec = "Base64" - ) => { - if (!priKey) return "缺少私钥"; - priKey = dataConv(priKey, priKeyCodec, "Hex"); - cipher = dataConv(cipher, codec, "Hex"); - let msg = SM.sm2.doDecrypt(cipher, priKey, cipherMode, { - output: "array", - }); - if (!msg?.length) throw "解密失败"; - return bytesArrayToStr(msg); - }, -}; diff --git a/plugin/lib/SymmetricEncryption.js b/plugin/lib/SymmetricEncryption.js deleted file mode 100644 index b0c6b35..0000000 --- a/plugin/lib/SymmetricEncryption.js +++ /dev/null @@ -1,280 +0,0 @@ -import CryptoJS from "crypto-js"; -import NodeForge from "node-forge"; -import { - strToWordArray, - forgeBytesToStr, - wordArrayToStr, - dataConv, -} from "@/script/Common.js"; - -let symmetricEncryptionParams = [ - { - type: "text", - name: "Key", - value: ["", "Utf8"], - options: ["Utf8", "Hex", "Base64"], - }, - { - type: "text", - name: "IV", - value: ["", "Utf8"], - options: ["Utf8", "Hex", "Base64"], - // name 会改变元素样式,额外增加ID作为唯一标识 - id: "IV", - }, - { - type: "list", - options: Object.keys(CryptoJS.mode), - value: "ECB", - // 根据banList禁用指定ID的元素,例如选中ECB时,禁用IV,ban和被ban的元素必须要有id - banList: { - ECB: ["IV"], - }, - id: "mode", - }, - { - type: "list", - options: [128, 192, 256], - value: 128, - }, - { - type: "list", - options: Object.keys(CryptoJS.pad), - value: "Pkcs7", - id: "padding", - }, - { type: "list", options: ["Base64", "Hex"], value: "Base64" }, -]; - -// AES添加GCM模式 -let symmetricEncryptionParamsAes = JSON.parse( - JSON.stringify(symmetricEncryptionParams) -); -symmetricEncryptionParamsAes[2].options.push("GCM"); -symmetricEncryptionParamsAes[2].banList.GCM = ["padding"]; - -// secret 格式为 hex字符串,方便补位 -const adjustSecLen = (hexSecret, len) => { - return hexSecret.length >= len * 2 - ? hexSecret.slice(0, len * 2) - : hexSecret + "00".repeat(len - hexSecret.length / 2); -}; - -export const processSecret = (secretWithCodec, len, to = "wordArray") => { - let [secret, codec] = secretWithCodec; - let hexSecret = dataConv(secret, codec, "Hex"); - let filledSecret = adjustSecLen(hexSecret, len); - return to === "wordArray" - ? CryptoJS.enc.Hex.parse(filledSecret) - : filledSecret; -}; - -// key/iv bytes -const forgeAesGcmEncrypt = (msg, key, iv, outputCodec, inputCodec) => { - var cipher = NodeForge.cipher.createCipher("AES-GCM", key); - cipher.start({ - iv: iv, - }); - cipher.update(NodeForge.util.createBuffer(msg, inputCodec)); - cipher.finish(); - var encrypted = cipher.output; - return { - enc: dataConv(encrypted.toHex(), "Hex", outputCodec), - tag: dataConv(cipher.mode.tag.toHex(), "Hex", outputCodec), - }; -}; - -// key/iv bytes -const forgeAesGcmDecrypt = (cipher, key, iv, tag, inputCodec) => { - cipher = NodeForge.util.createBuffer( - NodeForge.util.hexToBytes(dataConv(cipher, inputCodec, "Hex")) - ); - var decipher = NodeForge.cipher.createDecipher("AES-GCM", key); - decipher.start({ - iv: iv, - tag: NodeForge.util.hexToBytes(dataConv(tag, inputCodec, "Hex")), - }); - decipher.update(cipher); - var pass = decipher.finish(); - if (pass) { - return decipher.output.getBytes(); - } - return null; -}; - -export const AES = { - name: "AES", - params: symmetricEncryptionParamsAes, - encrypt: ( - msg, - key, - iv = "", - mode = "ECB", - keySize = 128, - padding = "Pkcs7", - outputCodec = "Base64", - { inputCodec } - ) => { - if (mode === "GCM") { - key = NodeForge.util.hexToBytes(processSecret(key, keySize / 8, "hex")); - iv = NodeForge.util.hexToBytes(processSecret(iv, 16, "hex")); - let result = forgeAesGcmEncrypt(msg, key, iv, outputCodec, inputCodec); - return JSON.stringify(result, null, 2); - } else { - let encrypted = CryptoJS.AES.encrypt( - strToWordArray(msg, inputCodec), - processSecret(key, keySize / 8, "wordArray"), - { - iv: processSecret(iv, 16, "wordArray"), - mode: CryptoJS.mode[mode], - padding: CryptoJS.pad[padding], - } - ); - return CryptoJS.enc[outputCodec].stringify(encrypted.ciphertext); - } - }, - decrypt: ( - cipher, - key, - iv = "", - mode = "ECB", - keySize = 128, - padding = "Pkcs7", - codec = "Base64" - ) => { - if (mode === "GCM") { - let format = `密文格式应为 {"enc":"hex or base64","tag":"hex or base64"}`; - try { - var { enc, tag } = JSON.parse(cipher); - } catch (_) { - throw new Error(format); - } - if (!enc || !tag) { - throw new Error(format); - } - key = NodeForge.util.hexToBytes(processSecret(key, keySize / 8, "hex")); - iv = NodeForge.util.hexToBytes(processSecret(iv, 16, "hex")); - let decrypted = forgeAesGcmDecrypt(enc, key, iv, tag, codec); - return forgeBytesToStr(decrypted); - } else { - cipher = dataConv(cipher, codec, "Base64"); - const decrypt = CryptoJS.AES.decrypt( - cipher, - processSecret(key, keySize / 8, "wordArray"), - { - iv: processSecret(iv, 16, "wordArray"), - mode: CryptoJS.mode[mode], - padding: CryptoJS.pad[padding], - } - ); - return wordArrayToStr(decrypt); - } - }, -}; - -export const DES = { - name: "DES", - params: symmetricEncryptionParams.filter((x, i) => i !== 3), - encrypt: ( - msg, - key, - iv = "", - mode = "ECB", - padding = "Pkcs7", - outputCodec = "Base64", - { inputCodec } - ) => { - const encrypted = CryptoJS.DES.encrypt( - strToWordArray(msg, inputCodec), - processSecret(key, 8, "wordArray"), - { - iv: processSecret(iv, 8, "wordArray"), - mode: CryptoJS.mode[mode], - padding: CryptoJS.pad[padding], - } - ); - return CryptoJS.enc[outputCodec].stringify(encrypted.ciphertext); - }, - decrypt: ( - cipher, - key, - iv = "", - mode = "ECB", - padding = "Pkcs7", - codec = "Base64" - ) => { - cipher = dataConv(cipher, codec, "Base64"); - const decrypt = CryptoJS.DES.decrypt( - cipher, - processSecret(key, 8, "wordArray"), - { - iv: processSecret(iv, 8, "wordArray"), - mode: CryptoJS.mode[mode], - padding: CryptoJS.pad[padding], - } - ); - return wordArrayToStr(decrypt); - }, -}; - -export const TripleDES = { - name: "TripleDES", - params: symmetricEncryptionParams.filter((x, i) => i !== 3), - encrypt: ( - msg, - key, - iv = "", - mode = "ECB", - padding = "Pkcs7", - outputCodec = "Base64", - { inputCodec } - ) => { - const encrypted = CryptoJS.TripleDES.encrypt( - strToWordArray(msg, inputCodec), - processSecret(key, 8, "wordArray"), - { - iv: processSecret(iv, 8, "wordArray"), - mode: CryptoJS.mode[mode], - padding: CryptoJS.pad[padding], - } - ); - return CryptoJS.enc[outputCodec].stringify(encrypted.ciphertext); - }, - decrypt: ( - cipher, - key, - iv = "", - mode = "ECB", - padding = "Pkcs7", - codec = "Base64" - ) => { - cipher = dataConv(cipher, codec, "Base64"); - const decrypt = CryptoJS.TripleDES.decrypt( - cipher, - processSecret(key, 8, "wordArray"), - { - iv: processSecret(iv, 8, "wordArray"), - mode: CryptoJS.mode[mode], - padding: CryptoJS.pad[padding], - } - ); - return wordArrayToStr(decrypt); - }, -}; - -export const rc4 = { - name: "RC4", - params: [{ type: "text", name: "Key", value: "" }], - encrypt: (msg, key, { inputCodec }) => - CryptoJS.RC4.encrypt(strToWordArray(msg, inputCodec), key).toString(), - decrypt: (cipher, key) => wordArrayToStr(CryptoJS.RC4.decrypt(cipher, key)), -}; - -export const rabbit = { - name: "Rabbit", - params: [{ type: "text", name: "Key", value: "" }], - encrypt: (msg, key, { inputCodec }) => - CryptoJS.Rabbit.encrypt(strToWordArray(msg, inputCodec), key).toString(), - decrypt: (cipher, key) => - wordArrayToStr(CryptoJS.Rabbit.decrypt(cipher, key)), -}; diff --git a/plugin/lib/quickcomposer/textProcessing.js b/plugin/lib/quickcomposer/textProcessing.js index 34b0c54..dff40d0 100644 --- a/plugin/lib/quickcomposer/textProcessing.js +++ b/plugin/lib/quickcomposer/textProcessing.js @@ -71,6 +71,140 @@ const textProcessing = { hexDecode: function (text) { return dataConv(text, "hex", "utf8"); }, + // MD5 哈希 + md5Hash: function (text) { + return NodeForge.md.md5.create().update(text).digest().toHex(); + }, + // SHA1 哈希 + sha1Hash: function (text) { + return NodeForge.md.sha1.create().update(text).digest().toHex(); + }, + // SHA256 哈希 + sha256Hash: function (text) { + return NodeForge.md.sha256.create().update(text).digest().toHex(); + }, + // SHA512 哈希 + sha512Hash: function (text) { + return NodeForge.md.sha512.create().update(text).digest().toHex(); + }, + // SM3 哈希 + sm3Hash: function (text) { + return sm3(text); + }, + // 字符串反转 + reverseString: function (text) { + return text.split("").reverse().join(""); + }, + // 字符串替换 + replaceString: function (text, oldStr, newStr) { + return text.replace(oldStr, newStr); + }, + // 字符串截取 + substring: function (text, start, end) { + return text.substring(start, end); + }, + // 正则提取 + regexExtract: function (text, regex) { + const match = text.match(regex); + return match ? match[0] : ""; + }, + // 非对称加解密 + asymmetricCrypto: function (config) { + const { + text, + algorithm, + operation, + format = "Base64", + publicKey = { key: "", codec: "Pem" }, + privateKey = { key: "", codec: "Pem" }, + padding = "RSAES-PKCS1-V1_5", + cipherMode = 1, + } = config; + + if (algorithm === "SM2") { + if (operation === "encrypt") { + if (!publicKey.key) throw "缺少公钥"; + // 转换公钥格式 + const hexPubKey = + publicKey.codec === "Hex" + ? publicKey.key + : dataConv(publicKey.key, publicKey.codec, "Hex"); + // 加密 + const cipher = sm2.doEncrypt(text, hexPubKey, cipherMode); + // 转换输出格式 + return format === "Base64" ? dataConv(cipher, "Hex", "Base64") : cipher; + } else { + if (!privateKey.key) throw "缺少私钥"; + // 转换私钥格式 + const hexPriKey = + privateKey.codec === "Hex" + ? privateKey.key + : dataConv(privateKey.key, privateKey.codec, "Hex"); + // 转换输入格式 + const hexCipher = + format === "Base64" ? dataConv(text, "Base64", "Hex") : text; + // 解密 + const msg = sm2.doDecrypt(hexCipher, hexPriKey, cipherMode, { + output: "utf8", + }); + if (!msg) throw "解密失败"; + return msg; + } + } else if (algorithm === "RSA") { + if (operation === "encrypt") { + if (!publicKey.key) throw "缺少公钥"; + // 转换公钥格式 + let formattedPubKey = publicKey.key; + if (publicKey.codec !== "Pem") { + formattedPubKey = + "-----BEGIN RSA PUBLIC KEY-----\n" + + dataConv(publicKey.key, publicKey.codec, "Base64") + + "\n-----END RSA PUBLIC KEY-----"; + } + formattedPubKey = formattedPubKey.replace(/\\n/g, "\n"); + + // 创建 RSA 公钥对象 + const publicKeyObj = NodeForge.pki.publicKeyFromPem(formattedPubKey); + // 将文本转换为二进制数据 + const binaryData = NodeForge.util.encodeUtf8(text); + // 使用指定的填充方式加密 + const encrypted = publicKeyObj.encrypt(binaryData, padding); + // 转换输出格式 + return format === "Base64" + ? dataConv(encrypted, "binary", "Base64") + : dataConv(encrypted, "binary", "Hex"); + } else { + if (!privateKey.key) throw "缺少私钥"; + // 转换私钥格式 + let formattedPriKey = privateKey.key; + if (privateKey.codec !== "Pem") { + formattedPriKey = + "-----BEGIN RSA PRIVATE KEY-----\n" + + dataConv(privateKey.key, privateKey.codec, "Base64") + + "\n-----END RSA PRIVATE KEY-----"; + } + formattedPriKey = formattedPriKey.replace(/\\n/g, "\n"); + + // 创建 RSA 私钥对象 + const privateKeyObj = NodeForge.pki.privateKeyFromPem(formattedPriKey); + // 转换输入格式 + const binary = + format === "Base64" + ? dataConv(text, "Base64", "binary") + : dataConv(text, "Hex", "binary"); + // 解密 + try { + const decrypted = privateKeyObj.decrypt(binary, padding); + // 将二进制数据转换回文本 + return NodeForge.util.decodeUtf8(decrypted); + } catch (e) { + console.error(e); + throw "解密失败"; + } + } + } + throw "不支持的算法"; + }, // 对称加解密 symmetricCrypto: function (config) { const { @@ -224,160 +358,6 @@ const textProcessing = { return CryptoJS.enc.Utf8.stringify(decrypted); } }, - // RSA 加密 - rsaEncrypt: function (text, key) { - return crypto.publicEncrypt(key, Buffer.from(text)).toString("base64"); - }, - // RSA 解密 - rsaDecrypt: function (text, key) { - return crypto.privateDecrypt(key, Buffer.from(text, "base64")).toString(); - }, - // SM4 加密 - sm4Encrypt: function (text, key) { - // 将密钥转换为 16 进制字符串 - const hexKey = Buffer.from(key).toString("hex"); - return sm4.encrypt(text, hexKey); - }, - // SM4 解密 - sm4Decrypt: function (text, key) { - // 将密钥转换为 16 进制字符串 - const hexKey = Buffer.from(key).toString("hex"); - return sm4.decrypt(text, hexKey); - }, - // SM2 加密 - sm2Encrypt: function (text, key) { - return sm2.encrypt(text, key); - }, - // SM2 解密 - sm2Decrypt: function (text, key) { - return sm2.decrypt(text, key); - }, - // MD5 哈希 - md5Hash: function (text) { - return crypto.createHash("md5").update(text).digest("hex"); - }, - // SHA256 哈希 - sha256Hash: function (text) { - return crypto.createHash("sha256").update(text).digest("hex"); - }, - // SM3 哈希 - sm3Hash: function (text) { - return sm3(text); - }, - // 字符串反转 - reverseString: function (text) { - return text.split("").reverse().join(""); - }, - // 字符串替换 - replaceString: function (text, oldStr, newStr) { - return text.replace(oldStr, newStr); - }, - // 字符串截取 - substring: function (text, start, end) { - return text.substring(start, end); - }, - // 正则提取 - regexExtract: function (text, regex) { - const match = text.match(regex); - return match ? match[0] : ""; - }, - // 非对称加解密 - asymmetricCrypto: function (config) { - const { - text, - algorithm, - operation, - format = "Base64", - publicKey = { key: "", codec: "Pem" }, - privateKey = { key: "", codec: "Pem" }, - padding = "RSAES-PKCS1-V1_5", - cipherMode = 1, - } = config; - - if (algorithm === "SM2") { - if (operation === "encrypt") { - if (!publicKey.key) throw "缺少公钥"; - // 转换公钥格式 - const hexPubKey = - publicKey.codec === "Hex" - ? publicKey.key - : dataConv(publicKey.key, publicKey.codec, "Hex"); - // 加密 - const cipher = sm2.doEncrypt(text, hexPubKey, cipherMode); - // 转换输出格式 - return format === "Base64" ? dataConv(cipher, "Hex", "Base64") : cipher; - } else { - if (!privateKey.key) throw "缺少私钥"; - // 转换私钥格式 - const hexPriKey = - privateKey.codec === "Hex" - ? privateKey.key - : dataConv(privateKey.key, privateKey.codec, "Hex"); - // 转换输入格式 - const hexCipher = - format === "Base64" ? dataConv(text, "Base64", "Hex") : text; - // 解密 - const msg = sm2.doDecrypt(hexCipher, hexPriKey, cipherMode, { - output: "utf8", - }); - if (!msg) throw "解密失败"; - return msg; - } - } else if (algorithm === "RSA") { - if (operation === "encrypt") { - if (!publicKey.key) throw "缺少公钥"; - // 转换公钥格式 - let formattedPubKey = publicKey.key; - if (publicKey.codec !== "Pem") { - formattedPubKey = - "-----BEGIN RSA PUBLIC KEY-----\n" + - dataConv(publicKey.key, publicKey.codec, "Base64") + - "\n-----END RSA PUBLIC KEY-----"; - } - formattedPubKey = formattedPubKey.replace(/\\n/g, "\n"); - - // 创建 RSA 公钥对象 - const publicKeyObj = NodeForge.pki.publicKeyFromPem(formattedPubKey); - // 将文本转换为二进制数据 - const binaryData = NodeForge.util.encodeUtf8(text); - // 使用指定的填充方式加密 - const encrypted = publicKeyObj.encrypt(binaryData, padding); - // 转换输出格式 - return format === "Base64" - ? dataConv(encrypted, "binary", "Base64") - : dataConv(encrypted, "binary", "Hex"); - } else { - if (!privateKey.key) throw "缺少私钥"; - // 转换私钥格式 - let formattedPriKey = privateKey.key; - if (privateKey.codec !== "Pem") { - formattedPriKey = - "-----BEGIN RSA PRIVATE KEY-----\n" + - dataConv(privateKey.key, privateKey.codec, "Base64") + - "\n-----END RSA PRIVATE KEY-----"; - } - formattedPriKey = formattedPriKey.replace(/\\n/g, "\n"); - - // 创建 RSA 私钥对象 - const privateKeyObj = NodeForge.pki.privateKeyFromPem(formattedPriKey); - // 转换输入格式 - const binary = - format === "Base64" - ? dataConv(text, "Base64", "binary") - : dataConv(text, "Hex", "binary"); - // 解密 - try { - const decrypted = privateKeyObj.decrypt(binary, padding); - // 将二进制数据转换回文本 - return NodeForge.util.decodeUtf8(decrypted); - } catch (e) { - console.error(e); - throw "解密失败"; - } - } - } - throw "不支持的算法"; - }, }; module.exports = textProcessing; diff --git a/src/components/editor/composer/ComposerCard.vue b/src/components/editor/composer/ComposerCard.vue index 859fea8..a1a8be3 100644 --- a/src/components/editor/composer/ComposerCard.vue +++ b/src/components/editor/composer/ComposerCard.vue @@ -93,8 +93,10 @@