style(system): 登录后更新部门信息功能调整

This commit is contained in:
2026-06-12 11:49:44 +08:00
parent 0b6b5856d1
commit 7acee51892
2 changed files with 361 additions and 3 deletions
@@ -3,12 +3,20 @@ package com.renkang.anyan.utils;
import cn.hutool.core.util.StrUtil;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
@@ -29,7 +37,7 @@ public class StringUtils {
public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
// 返回按照 X.509 标准进行编码的密钥的字节
// x509EncodedKeySpec2 是一种规范、规格
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(org.apache.commons.codec.binary.Base64.decodeBase64(publicKeyText));
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 让密钥工厂按照指定的 规范 生成公钥
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
@@ -40,7 +48,8 @@ public class StringUtils {
byte[] result = cipher.doFinal(text.getBytes());
// 返回 Base64编码的字符串
return org.apache.commons.codec.binary.Base64.encodeBase64String(result);
return Base64.getEncoder().encodeToString(result);
// return org.apache.commons.codec.binary.Base64.encodeBase64String(result);
}
@@ -112,4 +121,122 @@ public class StringUtils {
return filePath.getFileName().toString();
}
}
// ------------------- AES 加解密(带盐值处理)-------------------
/** 内部密钥,仅用于日志脱敏,非高强度安全场景 */
private static final String AES_PASSWORD = "XJPlatform@2024#Secure";
/** 盐值长度(字节) */
private static final int SALT_LENGTH = 8;
/** 初始化向量长度(字节) */
private static final int IV_LENGTH = 16;
/** AES 密钥长度 */
private static final int KEY_LENGTH = 128;
/** PBKDF2 迭代次数 */
private static final int PBKDF2_ITERATIONS = 1000;
/** AES 加密算法 */
private static final String AES_CIPHER = "AES/CBC/PKCS5Padding";
/**
* AES 加密(带随机盐值和 IV,每次加密结果不同)
*
* @param plainText 明文
* @return Base64 密文(格式:盐值 + IV + 加密数据)
*/
public static String aesEncrypt(String plainText) {
if (plainText == null || plainText.isEmpty()) {
return plainText;
}
try {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[SALT_LENGTH];
byte[] iv = new byte[IV_LENGTH];
random.nextBytes(salt);
random.nextBytes(iv);
SecretKeySpec keySpec = deriveKey(salt);
Cipher cipher = Cipher.getInstance(AES_CIPHER);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));
byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
byte[] combined = new byte[SALT_LENGTH + IV_LENGTH + encrypted.length];
System.arraycopy(salt, 0, combined, 0, SALT_LENGTH);
System.arraycopy(iv, 0, combined, SALT_LENGTH, IV_LENGTH);
System.arraycopy(encrypted, 0, combined, SALT_LENGTH + IV_LENGTH, encrypted.length);
return Base64.getEncoder().encodeToString(combined);
} catch (Exception e) {
System.err.println("AES加密失败: " + e.getMessage());
e.printStackTrace();
return plainText;
}
}
/**
* AES 解密(解析盐值 + IV + 加密数据)
*
* @param cipherText Base64 密文
* @return 明文
*/
public static String aesDecrypt(String cipherText) {
if (cipherText == null || cipherText.isEmpty()) {
return cipherText;
}
try {
byte[] combined = Base64.getDecoder().decode(cipherText);
byte[] salt = new byte[SALT_LENGTH];
byte[] iv = new byte[IV_LENGTH];
byte[] encrypted = new byte[combined.length - SALT_LENGTH - IV_LENGTH];
System.arraycopy(combined, 0, salt, 0, SALT_LENGTH);
System.arraycopy(combined, SALT_LENGTH, iv, 0, IV_LENGTH);
System.arraycopy(combined, SALT_LENGTH + IV_LENGTH, encrypted, 0, encrypted.length);
SecretKeySpec keySpec = deriveKey(salt);
Cipher cipher = Cipher.getInstance(AES_CIPHER);
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
byte[] decrypted = cipher.doFinal(encrypted);
return new String(decrypted, StandardCharsets.UTF_8);
} catch (Exception e) {
System.err.println("AES解密失败: " + e.getMessage());
e.printStackTrace();
return cipherText;
}
}
/**
* 通过 PBKDF2 从盐值和内部密钥派生 AES 密钥
*/
private static SecretKeySpec deriveKey(byte[] salt) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(AES_PASSWORD.toCharArray(), salt, PBKDF2_ITERATIONS, KEY_LENGTH);
SecretKey tmp = factory.generateSecret(spec);
return new SecretKeySpec(tmp.getEncoded(), "AES");
} catch (Exception e) {
throw new RuntimeException("派生AES密钥失败", e);
}
}
public static void main(String[] args) throws Exception {
// --- RSA 公钥加密测试(安眼平台)---
// String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJL0JkqsUoK6kt3JyogsgqNp9VDGDp+t3ZAGMbVoMPdHNT2nfiIVh9ZMNHF7g2XiAa8O8AQWyh2PjMR0NiUSVQMCAwEAAQ==";
// String password = "Aa%13999527523";
// String rsaEncrypted = encryptByPublicKey(publicKey, password);
// System.out.println("RSA加密: " + rsaEncrypted);
//
// // --- AES 加解密测试(日志脱敏)---
// String originalText = "Aa%13999527523";
// String aesEncrypted = aesEncrypt(originalText);
String aesDecrypted = aesDecrypt("RuKy7jFDJR0rEJiwxgcyX6RFq8qP5FEgWZuMNxuVkKlbHhjJ2SzLOA==");
// System.out.println("AES加密: " + aesEncrypted);
System.out.println("AES解密: " + aesDecrypted);
// System.out.println("匹配: " + originalText.equals(aesDecrypted));
// 验证每次加密结果不同(盐值和IV随机)
// String aesEncrypted2 = aesEncrypt(originalText);
// System.out.println("再次加密: " + aesEncrypted2);
// System.out.println("两次密文不同: " + !aesEncrypted.equals(aesEncrypted2));
}
}