添加统一门户的身份证/手机号解密
This commit is contained in:
@@ -0,0 +1,134 @@
|
|||||||
|
package com.ruoyi.common.utils.encrypt;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSON;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
|
public class EncryptUtil {
|
||||||
|
|
||||||
|
private static final String ALGORITHM = "AES";
|
||||||
|
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String appId = "cloud-9793ee8a8c3d47b8871007ffc4128502";
|
||||||
|
String appSecret = "Yi+NACK70UPg8rFvsnnfBUq1wcLD4nm6ilC4II/4C4k=";
|
||||||
|
String generatedIv = generateAppIV(appId);
|
||||||
|
String generatedKey = generateAppKey(appId, appSecret);
|
||||||
|
|
||||||
|
String data = "n+Rq0Y+quYHa9uL+EpWbuw==";
|
||||||
|
String str = decrypt(data, generatedIv, generatedKey);
|
||||||
|
System.err.println(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String generateAppIV(String appId) {
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] hashBytes = md.digest(appId.getBytes("UTF-8"));
|
||||||
|
// 直接使用字节数组转换,确保精确的16字节
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
String hex = Integer.toHexString(0xff & hashBytes[i]);
|
||||||
|
if (hex.length() == 1) {
|
||||||
|
sb.append('0');
|
||||||
|
}
|
||||||
|
sb.append(hex);
|
||||||
|
}
|
||||||
|
return sb.toString().substring(0, 16); // 确保正好16个字符
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("IV生成失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String generateAppKey(String appId, String appSecret) {
|
||||||
|
try {
|
||||||
|
String combinedKey = appId + appSecret;
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
|
byte[] hashBytes = md.digest(combinedKey.getBytes("UTF-8"));
|
||||||
|
// 取前16字节作为AES密钥
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
sb.append(Integer.toHexString((hashBytes[i] & 0xFF) | 0x100).substring(1, 3));
|
||||||
|
}
|
||||||
|
return sb.toString().substring(0, 16); // AES-128需要16字符密钥
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("密钥生成失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decrypt(String content, String iv, String key) {if(StringUtils.isEmpty(content)) {return "";}
|
||||||
|
iv = getIv( iv);
|
||||||
|
try {
|
||||||
|
byte[] decoded = Base64.decodeBase64(content);
|
||||||
|
byte[] decrypted = AES_CBC_Decrypt(decoded, iv, AES_normalizeKey(key));
|
||||||
|
String result = new String(decrypted, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
// 清理可能的填充字符
|
||||||
|
result = result.trim();
|
||||||
|
if (result.endsWith("\0")) {
|
||||||
|
result = result.replaceAll("\\\\0+$", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理JSON格式
|
||||||
|
String cleanResult = result.replaceAll("\"", "");
|
||||||
|
if (cleanResult.startsWith("{") && cleanResult.endsWith("}")) {
|
||||||
|
JSON parse = JSONUtil.parse(cleanResult);
|
||||||
|
return String.valueOf(parse);
|
||||||
|
} else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getIv(String iv) {
|
||||||
|
return generateIV(iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String generateIV(String iv) {
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] hashBytes = md.digest(iv.getBytes("UTF-8"));
|
||||||
|
// 直接使用字节数组转换,确保精确的16字节
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
String hex = Integer.toHexString(0xff & hashBytes[i]);
|
||||||
|
if (hex.length() == 1) {
|
||||||
|
sb.append('0');
|
||||||
|
}
|
||||||
|
sb.append(hex);
|
||||||
|
}
|
||||||
|
return sb.toString().substring(0, 16); // 确保正好16个字符
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("IV生成失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES CBC 解密
|
||||||
|
*/
|
||||||
|
private static byte[] AES_CBC_Decrypt(byte[] content, String iv, String key) throws Exception {
|
||||||
|
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
|
||||||
|
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
|
||||||
|
return cipher.doFinal(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 规范化密钥长度为16位(AES-128)
|
||||||
|
*/
|
||||||
|
private static String AES_normalizeKey(String key) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user