diff --git a/core/api/src/main/java/com/wansenai/api/user/SysUserController.java b/core/api/src/main/java/com/wansenai/api/user/SysUserController.java index 0d28d2d0..7af52f0f 100644 --- a/core/api/src/main/java/com/wansenai/api/user/SysUserController.java +++ b/core/api/src/main/java/com/wansenai/api/user/SysUserController.java @@ -55,7 +55,7 @@ public Response accountLogin(@RequestBody AccountLoginDTO accountLog } @PostMapping(value = "mobileLogin") - public Response accountLogin(@RequestBody MobileLoginDTO mobileLoginDto) { + public Response mobileLogin(@RequestBody MobileLoginDTO mobileLoginDto) { return userService.mobileLogin(mobileLoginDto); } diff --git a/core/service/src/main/java/com/wansenai/service/user/impl/SysUserServiceImpl.java b/core/service/src/main/java/com/wansenai/service/user/impl/SysUserServiceImpl.java index 15d77c5f..e96e0ded 100644 --- a/core/service/src/main/java/com/wansenai/service/user/impl/SysUserServiceImpl.java +++ b/core/service/src/main/java/com/wansenai/service/user/impl/SysUserServiceImpl.java @@ -20,6 +20,7 @@ import com.wansenai.middleware.oss.TencentOSS; import com.wansenai.service.system.ISysPlatformConfigService; import com.wansenai.utils.CommonTools; +import com.wansenai.utils.CryptoUtils; import com.wansenai.utils.FileUtil; import com.wansenai.utils.SnowflakeIdUtil; import com.wansenai.dto.user.*; @@ -137,13 +138,25 @@ public Response accountRegister(AccountRegisterDTO accountRegisterDto) { return Response.responseMsg(UserCodeEnum.USER_REGISTER_PHONE_EXISTS); } + var password = ""; + try { + password = CryptoUtils.decryptSymmetrically(SecurityConstants.REGISTER_SECURITY_KEY, null, + accountRegisterDto.getPassword(), CryptoUtils.Algorithm.Encryption.AES_ECB_PKCS5); + } catch (Exception e) { + log.error("密码解密失败: " + e.getMessage()); + } + + if (!StringUtils.hasLength(password)) { + return Response.responseMsg(BaseCodeEnum.ERROR.getCode(), "密码解密失败"); + } + // start register var userId = SnowflakeIdUtil.nextId(); var user = SysUser.builder() .id(userId) .userName(accountRegisterDto.getUsername()) .name("测试租户") - .password(CommonTools.md5Encryp(accountRegisterDto.getPassword())) + .password(CommonTools.md5Encryp(password)) .phoneNumber(accountRegisterDto.getPhoneNumber()) .tenantId(userId) .createTime(LocalDateTime.now()) @@ -230,7 +243,7 @@ public Response accountRegister(AccountRegisterDTO accountRegisterDto) { } @Override - public Response accountLogin(AccountLoginDTO accountLoginDto) { + public Response accountLogin(AccountLoginDTO accountLoginDto){ var verifyCode = redisUtil.get(SecurityConstants.EMAIL_VERIFY_CODE_CACHE_PREFIX + accountLoginDto.getCaptchaId()); if (ObjectUtils.isEmpty(verifyCode)) { @@ -240,10 +253,17 @@ public Response accountLogin(AccountLoginDTO accountLoginDto) { if (!String.valueOf(verifyCode).equals(accountLoginDto.getCaptcha())) { return Response.responseMsg(BaseCodeEnum.VERIFY_CODE_ERROR); } - + var password = ""; + try { + password = CryptoUtils.decryptSymmetrically(SecurityConstants.LOGIN_SECURITY_KEY, null, + accountLoginDto.getPassword(), CryptoUtils.Algorithm.Encryption.AES_ECB_PKCS5); + } catch (Exception e) { + log.error("密码解密失败: " + e.getMessage()); + return Response.responseMsg(UserCodeEnum.USERNAME_OR_PASSWORD_ERROR); + } var user = lambdaQuery() .eq(SysUser::getUserName, accountLoginDto.getUsername()) - .eq(SysUser::getPassword, CommonTools.md5Encryp(accountLoginDto.getPassword())) + .eq(SysUser::getPassword, CommonTools.md5Encryp(password)) .one(); if (user == null) { diff --git a/core/utils/src/main/java/com/wansenai/utils/CryptoUtils.java b/core/utils/src/main/java/com/wansenai/utils/CryptoUtils.java new file mode 100644 index 00000000..7bb5e211 --- /dev/null +++ b/core/utils/src/main/java/com/wansenai/utils/CryptoUtils.java @@ -0,0 +1,400 @@ +/* + * Copyright 2023-2033 WanSen AI Team, Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://opensource.wansenai.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.wansenai.utils; + +import io.micrometer.common.util.StringUtils; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import java.util.Base64.Decoder; +import java.util.Base64.Encoder; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 支持AES、DES、RSA加密、数字签名以及生成对称密钥和非对称密钥对 + */ +public class CryptoUtils { + + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + private static final Encoder BASE64_ENCODER = Base64.getEncoder(); + private static final Decoder BASE64_DECODER = Base64.getDecoder(); + + private static final Map KEY_FACTORY_CACHE = new ConcurrentHashMap<>(); + private static final Map CIPHER_CACHE = new HashMap<>(); + + /** + * 生成对称密钥,目前支持的算法有AES、DES + * @param algorithm + * @return + * @throws NoSuchAlgorithmException + */ + public static String generateSymmetricKey(Algorithm algorithm) throws NoSuchAlgorithmException { + KeyGenerator generator = KeyGenerator.getInstance(algorithm.getName()); + generator.init(algorithm.getKeySize()); + SecretKey secretKey = generator.generateKey(); + return BASE64_ENCODER.encodeToString(secretKey.getEncoded()); + } + + /** + * 生成非对称密钥对,目前支持的算法有RSA、DSA。备注:默认生成的密钥格式为PKCS8 + * @param algorithm + * @return + * @throws NoSuchAlgorithmException + */ + public static AsymmetricKeyPair generateAsymmetricKeyPair(Algorithm algorithm) throws NoSuchAlgorithmException { + KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm.getName()); + generator.initialize(algorithm.getKeySize()); + KeyPair keyPair = generator.generateKeyPair(); + String publicKey = BASE64_ENCODER.encodeToString(keyPair.getPublic().getEncoded()); + String privateKey = BASE64_ENCODER.encodeToString(keyPair.getPrivate().getEncoded()); + return new AsymmetricKeyPair(publicKey, privateKey); + } + + public static String encryptByRSA(String publicKeyText, String plainText) throws Exception { + return encryptAsymmetrically(publicKeyText, plainText, Algorithm.Encryption.RSA_ECB_PKCS1); + } + + public static String decryptByRSA(String privateKeyText, String ciphertext) throws Exception { + return decryptAsymmetrically(privateKeyText, ciphertext, Algorithm.Encryption.RSA_ECB_PKCS1); + } + + /** + * SHA1签名算法和DSA加密算法结合使用生成数字签名 + * @param privateKeyText + * @param msg + * @return 数字签名 + * @throws Exception + */ + public static String signBySHA1WithDSA(String privateKeyText, String msg) throws Exception { + return doSign(privateKeyText, msg, Algorithm.Encryption.DSA, Algorithm.Signing.SHA1WithDSA); + } + + /** + * SHA1签名算法和RSA加密算法结合使用生成数字签名 + * @param privateKeyText 私钥 + * @param msg 待加签内容 + * @return 数字签名 + * @throws Exception + */ + public static String signBySHA1WithRSA(String privateKeyText, String msg) throws Exception { + return doSign(privateKeyText, msg, Algorithm.Encryption.RSA_ECB_PKCS1, Algorithm.Signing.SHA1WithRSA); + } + + /** + * SHA256签名算法和RSA加密算法结合使用生成数字签名 + * @param privateKeyText 私钥 + * @param msg 待加签内容 + * @return 数字签名 + * @throws Exception + */ + public static String signBySHA256WithRSA(String privateKeyText, String msg) throws Exception { + return doSign(privateKeyText, msg, Algorithm.Encryption.RSA_ECB_PKCS1, Algorithm.Signing.SHA256WithRSA); + } + + /** + * SHA1签名算法和DSA加密算法检验数字签名 + * @param publicKeyText 公钥 + * @param msg 待验签内容 + * @param signatureText 数字 + * @return 检验是否成功 + * @throws Exception + */ + public static boolean verifyBySHA1WithDSA(String publicKeyText, String msg, String signatureText) throws Exception { + return doVerify(publicKeyText, msg, signatureText, Algorithm.Encryption.DSA, Algorithm.Signing.SHA1WithDSA); + } + + /** + * SHA1签名算法和RSA加密算法检验数字签名 + * @param publicKeyText 公钥 + * @param msg 待验签内容 + * @param signatureText 签名 + * @return 校验是否成功 + * @throws Exception + */ + public static boolean verifyBySHA1WithRSA(String publicKeyText, String msg, String signatureText) throws Exception { + return doVerify(publicKeyText, msg, signatureText, Algorithm.Encryption.RSA_ECB_PKCS1, Algorithm.Signing.SHA1WithRSA); + } + + /** + * SHA256签名算法和RSA加密算法检验数字签名 + * @param publicKeyText 公钥 + * @param msg 待验签内容 + * @param signatureText 签名 + * @return 校验是否成功 + * @throws Exception + */ + public static boolean verifyBySHA256WithRSA(String publicKeyText, String msg, String signatureText) throws Exception { + return doVerify(publicKeyText, msg, signatureText, Algorithm.Encryption.RSA_ECB_PKCS1, Algorithm.Signing.SHA256WithRSA); + } + + /** + * 对称加密 + * @param secretKey 密钥 + * @param iv 加密向量,只有CBC模式才支持,如果是CBC则必传 + * @param plainText 明文 + * @param algorithm 对称加密算法,如AES、DES + * @return + * @throws Exception + */ + public static String encryptSymmetrically(String secretKey, String iv, String plainText, Algorithm algorithm) throws Exception { + SecretKey key = decodeSymmetricKey(secretKey, algorithm); + IvParameterSpec ivParameterSpec = StringUtils.isBlank(iv) ? null : decodeIv(iv); + byte[] plainTextInBytes = plainText.getBytes(DEFAULT_CHARSET); + byte[] ciphertextInBytes = transform(algorithm, Cipher.ENCRYPT_MODE, key, ivParameterSpec, plainTextInBytes); + + return BASE64_ENCODER.encodeToString(ciphertextInBytes); + } + + /** + * 对称解密 + * @param secretKey 密钥 + * @param iv 加密向量,只有CBC模式才支持,如果是CBC则必传 + * @param ciphertext 密文 + * @param algorithm 对称加密算法,如AES、DES + * @return + * @throws Exception + */ + public static String decryptSymmetrically(String secretKey, String iv, String ciphertext, Algorithm algorithm) throws Exception { + SecretKey key = decodeSymmetricKey(secretKey, algorithm); + IvParameterSpec ivParameterSpec = StringUtils.isBlank(iv) ? null : decodeIv(iv); + byte[] ciphertextInBytes = BASE64_DECODER.decode(ciphertext); + byte[] plainTextInBytes = transform(algorithm, Cipher.DECRYPT_MODE, key, ivParameterSpec, ciphertextInBytes); + return new String(plainTextInBytes, DEFAULT_CHARSET); + } + + /** + * 非对称加密 + * @param publicKeyText 公钥 + * @param plainText 明文 + * @param algorithm 非对称加密算法 + * @return + * @throws Exception + */ + public static String encryptAsymmetrically(String publicKeyText, String plainText, Algorithm algorithm) throws Exception { + PublicKey publicKey = regeneratePublicKey(publicKeyText, algorithm); + byte[] plainTextInBytes = plainText.getBytes(DEFAULT_CHARSET); + byte[] ciphertextInBytes = transform(algorithm, Cipher.ENCRYPT_MODE, publicKey, plainTextInBytes); + return BASE64_ENCODER.encodeToString(ciphertextInBytes); + } + + /** + * 非对称解密 + * @param privateKeyText 私钥 + * @param ciphertext 密文 + * @param algorithm 非对称加密算法 + * @return + * @throws Exception + */ + public static String decryptAsymmetrically(String privateKeyText, String ciphertext, Algorithm algorithm) throws Exception { + PrivateKey privateKey = regeneratePrivateKey(privateKeyText, algorithm); + byte[] ciphertextInBytes = BASE64_DECODER.decode(ciphertext); + byte[] plainTextInBytes = transform(algorithm, Cipher.DECRYPT_MODE, privateKey, ciphertextInBytes); + return new String(plainTextInBytes, DEFAULT_CHARSET); + } + + /** + * 生成数字签名 + * @param privateKeyText 私钥 + * @param msg 传输的数据 + * @param encryptionAlgorithm 加密算法,见Algorithm中的加密算法 + * @param signatureAlgorithm 签名算法,见Algorithm中的签名算法 + * @return 数字签名 + * @throws Exception + */ + public static String doSign(String privateKeyText, String msg, Algorithm encryptionAlgorithm, Algorithm signatureAlgorithm) + throws Exception { + PrivateKey privateKey = regeneratePrivateKey(privateKeyText, encryptionAlgorithm); + // Signature只支持签名算法 + Signature signature = Signature.getInstance(signatureAlgorithm.getName()); + signature.initSign(privateKey); + signature.update(msg.getBytes(DEFAULT_CHARSET)); + byte[] signatureInBytes = signature.sign(); + return BASE64_ENCODER.encodeToString(signatureInBytes); + } + + /** + * 数字签名验证 + * @param publicKeyText 公钥 + * @param msg 传输的数据 + * @param signatureText 数字签名 + * @param encryptionAlgorithm 加密算法,见Algorithm中的加密算法 + * @param signatureAlgorithm 签名算法,见Algorithm中的签名算法 + * @return 校验是否成功 + * @throws Exception + */ + public static boolean doVerify(String publicKeyText, String msg, String signatureText, Algorithm encryptionAlgorithm, + Algorithm signatureAlgorithm) throws Exception { + PublicKey publicKey = regeneratePublicKey(publicKeyText, encryptionAlgorithm); + Signature signature = Signature.getInstance(signatureAlgorithm.getName()); + signature.initVerify(publicKey); + signature.update(msg.getBytes(DEFAULT_CHARSET)); + return signature.verify(BASE64_DECODER.decode(signatureText)); + } + + /** + * 将密钥进行Base64位解码,重新生成SecretKey实例 + * @param secretKey 密钥 + * @param algorithm 算法 + * @return + */ + private static SecretKey decodeSymmetricKey(String secretKey, Algorithm algorithm) { + byte[] key = BASE64_DECODER.decode(secretKey); + return new SecretKeySpec(key, algorithm.getName()); + } + + private static IvParameterSpec decodeIv(String iv) { + byte[] ivInBytes = BASE64_DECODER.decode(iv); + return new IvParameterSpec(ivInBytes); + } + + private static PublicKey regeneratePublicKey(String publicKeyText, Algorithm algorithm) + throws NoSuchAlgorithmException, InvalidKeySpecException { + byte[] keyInBytes = BASE64_DECODER.decode(publicKeyText); + KeyFactory keyFactory = getKeyFactory(algorithm); + // 公钥必须使用RSAPublicKeySpec或者X509EncodedKeySpec + KeySpec publicKeySpec = new X509EncodedKeySpec(keyInBytes); + PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); + return publicKey; + } + + private static PrivateKey regeneratePrivateKey(String key, Algorithm algorithm) throws Exception { + byte[] keyInBytes = BASE64_DECODER.decode(key); + KeyFactory keyFactory = getKeyFactory(algorithm); + // 私钥必须使用RSAPrivateCrtKeySpec或者PKCS8EncodedKeySpec + KeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyInBytes); + PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); + return privateKey; + } + + private static KeyFactory getKeyFactory(Algorithm algorithm) throws NoSuchAlgorithmException { + KeyFactory keyFactory = KEY_FACTORY_CACHE.get(algorithm); + if (keyFactory == null) { + keyFactory = KeyFactory.getInstance(algorithm.getName()); + KEY_FACTORY_CACHE.put(algorithm, keyFactory); + } + + return keyFactory; + } + + private static byte[] transform(Algorithm algorithm, int mode, Key key, byte[] msg) throws Exception { + return transform(algorithm, mode, key, null, msg); + } + + private static byte[] transform(Algorithm algorithm, int mode, Key key, IvParameterSpec iv, byte[] msg) throws Exception { + Cipher cipher = CIPHER_CACHE.get(algorithm); + // double check,减少上下文切换 + if (cipher == null) { + synchronized (CryptoUtils.class) { + if ((cipher = CIPHER_CACHE.get(algorithm)) == null) { + cipher = determineWhichCipherToUse(algorithm); + CIPHER_CACHE.put(algorithm, cipher); + } + cipher.init(mode, key, iv); + return cipher.doFinal(msg); + } + } + + synchronized (CryptoUtils.class) { + cipher.init(mode, key, iv); + return cipher.doFinal(msg); + } + } + + private static Cipher determineWhichCipherToUse(Algorithm algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException { + Cipher cipher; + String transformation = algorithm.getTransformation(); + // 官方推荐的transformation使用algorithm/mode/padding组合,SunJCE使用ECB作为默认模式,使用PKCS5Padding作为默认填充 + if (StringUtils.isNotEmpty(transformation)) { + cipher = Cipher.getInstance(transformation); + } else { + cipher = Cipher.getInstance(algorithm.getName()); + } + + return cipher; + } + + /** + * 算法分为加密算法和签名算法,更多算法实现见:
+ * jdk8中的标准算法 + */ + public static class Algorithm { + + public interface Encryption { + Algorithm AES_ECB_PKCS5 = new Algorithm("AES", "AES/ECB/PKCS5Padding", 128); + Algorithm AES_CBC_PKCS5 = new Algorithm("AES", "AES/CBC/PKCS5Padding", 128); + Algorithm DES_ECB_PKCS5 = new Algorithm("DES", "DES/ECB/PKCS5Padding", 56); + Algorithm DES_CBC_PKCS5 = new Algorithm("DES", "DES/CBC/PKCS5Padding", 56); + Algorithm RSA_ECB_PKCS1 = new Algorithm("RSA", "RSA/ECB/PKCS1Padding", 1024); + Algorithm DSA = new Algorithm("DSA", 1024); + } + + public interface Signing { + Algorithm SHA1WithDSA = new Algorithm("SHA1withDSA", 1024); + Algorithm SHA1WithRSA = new Algorithm("SHA1WithRSA", 2048); + Algorithm SHA256WithRSA = new Algorithm("SHA256WithRSA", 2048); + } + + @Getter + private String name; + @Getter + private String transformation; + @Getter + private int keySize; + + public Algorithm(String name, int keySize) { + this(name, null, keySize); + } + + public Algorithm(String name, String transformation, int keySize) { + this.name = name; + this.transformation = transformation; + this.keySize = keySize; + } + + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class AsymmetricKeyPair { + + private String publicKey; + private String privateKey; + } + +} + diff --git a/core/utils/src/main/java/com/wansenai/utils/constants/SecurityConstants.java b/core/utils/src/main/java/com/wansenai/utils/constants/SecurityConstants.java index 5fc99254..d9660d38 100644 --- a/core/utils/src/main/java/com/wansenai/utils/constants/SecurityConstants.java +++ b/core/utils/src/main/java/com/wansenai/utils/constants/SecurityConstants.java @@ -30,6 +30,10 @@ public interface SecurityConstants { String EMAIL_RESET_VERIFY_CODE_CACHE_PREFIX = "AUTH:VERIFY_CODE:EMAIL_RESET:"; + String LOGIN_SECURITY_KEY = "QsCdA/3d8CkxZ6k5c6eA61=="; + + String REGISTER_SECURITY_KEY = "7Fd2u4qF/3k0z6O1c9AeC7=="; + /** * 用户权限集合缓存前缀 */ diff --git a/web/src/views/sys/login/LoginForm.vue b/web/src/views/sys/login/LoginForm.vue index 0e201d9f..cf55de47 100644 --- a/web/src/views/sys/login/LoginForm.vue +++ b/web/src/views/sys/login/LoginForm.vue @@ -114,7 +114,7 @@ import { useI18n } from '/@/hooks/web/useI18n'; import { useUserStore } from '/@/store/modules/user'; - import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin'; + import { LoginStateEnum, useLoginState, useFormRules, useFormValid, encryptByAES} from './useLogin'; import { useDesign } from '/@/hooks/web/useDesign'; import {PageEnum} from "@/enums/pageEnum"; import {useGo} from "@/hooks/web/usePage"; @@ -157,9 +157,12 @@ const data = await validForm(); if (!data) return; loading.value = true; + + const secretKey = 'QsCdA/3d8CkxZ6k5c6eA61=='; + const encryptedPassword = encryptByAES(data.password, secretKey); userStore .login({ - password: data.password, + password: encryptedPassword, username: data.account, captcha: data.captcha, captchaId: data.captchaId, diff --git a/web/src/views/sys/login/RegisterForm.vue b/web/src/views/sys/login/RegisterForm.vue index 58583081..b3ab96a0 100644 --- a/web/src/views/sys/login/RegisterForm.vue +++ b/web/src/views/sys/login/RegisterForm.vue @@ -75,10 +75,10 @@ import { CountdownInput } from '/@/components/CountDown'; import { useI18n } from '/@/hooks/web/useI18n'; import { - useLoginState, - useFormRules, - useFormValid, - LoginStateEnum, + useLoginState, + useFormRules, + useFormValid, + LoginStateEnum, encryptByAES, } from './useLogin'; import {register, sendSmsRegister} from '/@/api/sys/user' @@ -110,9 +110,11 @@ console.log(data); loading.value = true; + const secretKey = '7Fd2u4qF/3k0z6O1c9AeC7=='; + const encryptedPassword = encryptByAES(data.password, secretKey); const result = await register({ username: data.username, - password: data.password, + password: encryptedPassword, phoneNumber: data.phoneNumber, sms: data.sms, }); diff --git a/web/src/views/sys/login/useLogin.ts b/web/src/views/sys/login/useLogin.ts index 3540d368..fc2895b6 100644 --- a/web/src/views/sys/login/useLogin.ts +++ b/web/src/views/sys/login/useLogin.ts @@ -2,6 +2,7 @@ import type {ValidationRule, FormInstance} from 'ant-design-vue/lib/form/Form'; import type {RuleObject, NamePath} from 'ant-design-vue/lib/form/interface'; import {ref, computed, unref, Ref} from 'vue'; import {useI18n} from '/@/hooks/web/useI18n'; +import CryptoJS from 'crypto-js'; export enum LoginStateEnum { LOGIN, @@ -11,6 +12,37 @@ export enum LoginStateEnum { QR_CODE, } +/** + * AES加密 + * @param plainText 明文 + * @param keyInBase64Str base64编码后的key + * @returns {string} base64编码后的密文 + */ +export function encryptByAES(plainText, keyInBase64Str) { + let key = CryptoJS.enc.Base64.parse(keyInBase64Str); + let encrypted = CryptoJS.AES.encrypt(plainText, key, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7, + }); + return encrypted.ciphertext.toString(CryptoJS.enc.Base64); +} + +/** + * AES解密 + * @param cipherText 密文 + * @param keyInBase64Str base64编码后的key + * @return 明文 + */ +export function decryptByAES(cipherText, keyInBase64Str) { + let key = CryptoJS.enc.Base64.parse(keyInBase64Str); + let decrypted = CryptoJS.AES.decrypt(cipherText, key, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7, + }); + + return decrypted.toString(CryptoJS.enc.Utf8); +} + const currentState = ref(LoginStateEnum.LOGIN); // 这里也可以优化