style(system): 登录后更新部门信息功能调整
This commit is contained in:
+129
-2
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user