This commit is contained in:
parent
fc79b80e69
commit
0c99c66172
|
|
@ -21,7 +21,6 @@ public class EsDataEncryptUtil {
|
|||
private static final Set<String> DATE_FIELD_PREFIXES = new HashSet<>(Arrays.asList(
|
||||
"createTime", "updateTime", "lastTime", "startTime", "endTime", "birthDate", "nextContactTime"
|
||||
));
|
||||
|
||||
private static EncryptionService getEncryptionService() {
|
||||
if (encryptionService == null) {
|
||||
encryptionService = ApplicationContextHolder.getBean(EncryptionService.class);
|
||||
|
|
@ -63,7 +62,7 @@ public class EsDataEncryptUtil {
|
|||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
decryptedMap.put(key, decryptValue(value));
|
||||
decryptedMap.put(key, decryptValue(key,value));
|
||||
}
|
||||
return decryptedMap;
|
||||
}
|
||||
|
|
@ -133,7 +132,7 @@ public class EsDataEncryptUtil {
|
|||
* 根据值类型进行解密
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Object decryptValue(Object value) {
|
||||
private static Object decryptValue(String key,Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -142,7 +141,8 @@ public class EsDataEncryptUtil {
|
|||
String strValue = (String) value;
|
||||
// 对已加密的数据进行解密
|
||||
if (strValue.startsWith(Const.ENCRYPTED_PREFIX)) {
|
||||
return getEncryptionService().decryptAes(strValue.substring(Const.ENCRYPTED_PREFIX.length()));
|
||||
String newValue = getEncryptionService().decryptAes(strValue.substring(Const.ENCRYPTED_PREFIX.length()));
|
||||
return desensitization(key,newValue);
|
||||
}
|
||||
return strValue;
|
||||
} else if (value instanceof Map) {
|
||||
|
|
@ -152,7 +152,7 @@ public class EsDataEncryptUtil {
|
|||
// 递归处理List中的每个元素
|
||||
List<Object> decryptedList = new ArrayList<>();
|
||||
for (Object item : (List<Object>) value) {
|
||||
decryptedList.add(decryptValue(item));
|
||||
decryptedList.add(decryptValue(key,item));
|
||||
}
|
||||
return decryptedList;
|
||||
}
|
||||
|
|
@ -160,6 +160,19 @@ public class EsDataEncryptUtil {
|
|||
return value;
|
||||
}
|
||||
|
||||
// 数据脱敏
|
||||
private static String desensitization(String key,String value){
|
||||
if ("mobile".equals(key)) {
|
||||
return SensitiveDataMaskUtil.maskPhone(value);
|
||||
}else if ("email".equals(key)) {
|
||||
return SensitiveDataMaskUtil.maskEmail(value);
|
||||
}else if ("ownerDeptName".equals(key)) {
|
||||
return SensitiveDataMaskUtil.maskName(value);
|
||||
}else if ("address".equals(key)) {
|
||||
return SensitiveDataMaskUtil.maskAddress(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* 判断字段是否为日期类型字段
|
||||
* @param fieldName 字段名
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
package com.kakarote.core.security.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 敏感数据脱敏工具类
|
||||
* 提供姓名、手机号、地址等敏感信息的脱敏处理
|
||||
*/
|
||||
public class SensitiveDataMaskUtil {
|
||||
|
||||
/**
|
||||
* 对姓名进行脱敏处理
|
||||
* 规则:
|
||||
* 1. 单字名:显示姓氏,其余用*代替
|
||||
* 2. 双字名:显示姓氏,名用*代替
|
||||
* 3. 多字名:显示姓氏和最后一个字,中间用*代替
|
||||
* 4. 长度不足的情况:直接返回原字符串
|
||||
*
|
||||
* @param name 姓名
|
||||
* @return 脱敏后的姓名
|
||||
*/
|
||||
public static String maskName(String name) {
|
||||
if (StringUtils.isBlank(name)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
int length = name.length();
|
||||
if (length == 1) {
|
||||
// 单字名,直接返回
|
||||
return name;
|
||||
} else if (length == 2) {
|
||||
// 双字名,显示姓氏
|
||||
return name.charAt(0) + "*";
|
||||
} else if (length == 3) {
|
||||
// 三字名,显示姓氏和最后一个字
|
||||
return name.charAt(0) + "*" + name.charAt(2);
|
||||
} else {
|
||||
// 多字名,显示姓氏和最后一个字,中间用*代替
|
||||
return name.charAt(0) + StringUtils.repeat("*", length - 2) + name.charAt(length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对手机号码进行脱敏处理
|
||||
* 规则:保留前3位和后4位,中间用*代替
|
||||
*
|
||||
* @param phone 手机号码
|
||||
* @return 脱敏后的手机号码
|
||||
*/
|
||||
public static String maskPhone(String phone) {
|
||||
if (StringUtils.isBlank(phone) || phone.length() < 11) {
|
||||
return phone;
|
||||
}
|
||||
return phone.substring(0, 3) + "****" + phone.substring(7);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对地址进行脱敏处理
|
||||
* 规则:
|
||||
* 1. 保留省、市、区,后面的详细地址用*代替
|
||||
* 2. 如果地址较短,保留前8个字符,后面用*代替
|
||||
*
|
||||
* @param address 地址
|
||||
* @return 脱敏后的地址
|
||||
*/
|
||||
public static String maskAddress(String address) {
|
||||
if (StringUtils.isBlank(address)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
int length = address.length();
|
||||
if (length <= 8) {
|
||||
// 地址较短,保留前半部分
|
||||
int keepLength = Math.max(1, length / 2);
|
||||
return address.substring(0, keepLength) + StringUtils.repeat("*", length - keepLength);
|
||||
} else {
|
||||
// 地址较长,保留前8个字符
|
||||
return address.substring(0, 8) + "****";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对邮箱进行脱敏处理
|
||||
* 规则:保留前2位和域名,中间用*代替
|
||||
*
|
||||
* @param email 邮箱地址
|
||||
* @return 脱敏后的邮箱
|
||||
*/
|
||||
public static String maskEmail(String email) {
|
||||
if (StringUtils.isBlank(email) || !email.contains("@")) {
|
||||
return email;
|
||||
}
|
||||
|
||||
String[] parts = email.split("@");
|
||||
if (parts.length != 2) {
|
||||
return email;
|
||||
}
|
||||
|
||||
String username = parts[0];
|
||||
String domain = parts[1];
|
||||
|
||||
if (username.length() <= 2) {
|
||||
// 用户名较短,全部用*代替
|
||||
return StringUtils.repeat("*", username.length()) + "@" + domain;
|
||||
} else {
|
||||
// 保留前2位,其余用*代替
|
||||
return username.substring(0, 2) + StringUtils.repeat("*", username.length() - 2) + "@" + domain;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对身份证号进行脱敏处理
|
||||
* 规则:保留前6位和后4位,中间用*代替
|
||||
*
|
||||
* @param idCard 身份证号
|
||||
* @return 脱敏后的身份证号
|
||||
*/
|
||||
public static String maskIdCard(String idCard) {
|
||||
if (StringUtils.isBlank(idCard) || idCard.length() < 18) {
|
||||
return idCard;
|
||||
}
|
||||
return idCard.substring(0, 6) + StringUtils.repeat("*", 8) + idCard.substring(14);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用脱敏方法
|
||||
*
|
||||
* @param str 原始字符串
|
||||
* @param start 保留的开始位置(包含)
|
||||
* @param end 保留的结束位置(包含)
|
||||
* @return 脱敏后的字符串
|
||||
*/
|
||||
public static String maskGeneral(String str, int start, int end) {
|
||||
if (StringUtils.isBlank(str)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
int length = str.length();
|
||||
if (start < 0 || end < 0 || start >= length || end >= length || start >= end) {
|
||||
return str;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(str.substring(0, start));
|
||||
sb.append(StringUtils.repeat("*", end - start + 1));
|
||||
sb.append(str.substring(end + 1));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ import com.kakarote.core.common.SystemCodeEnum;
|
|||
import com.kakarote.core.exception.CrmException;
|
||||
import com.kakarote.core.feign.admin.entity.SimpleUser;
|
||||
import com.kakarote.core.field.FieldService;
|
||||
import com.kakarote.core.security.util.EsDataEncryptUtil;
|
||||
import com.kakarote.core.servlet.ApplicationContextHolder;
|
||||
import com.kakarote.core.utils.UserCacheUtil;
|
||||
import com.kakarote.crm.constant.CrmEnum;
|
||||
|
|
@ -458,10 +459,12 @@ public class InitEsIndexRunner implements ApplicationRunner {
|
|||
}
|
||||
}
|
||||
});
|
||||
// 在创建IndexRequest之前加密数据
|
||||
Map<String, Object> encryptedMap = EsDataEncryptUtil.encryptMap(map);
|
||||
|
||||
IndexRequest request = new IndexRequest(crmEnum.getIndex(), "_doc");
|
||||
request.id(map.get(crmEnum.getPrimaryKey()).toString());
|
||||
request.source(map);
|
||||
request.id(encryptedMap.get(crmEnum.getPrimaryKey()).toString());
|
||||
request.source(encryptedMap);
|
||||
bulkRequest.add(request);
|
||||
if (bulkRequest.requests().size() >= 1000) {
|
||||
bulk(bulkRequest);
|
||||
|
|
@ -510,7 +513,10 @@ public class InitEsIndexRunner implements ApplicationRunner {
|
|||
}
|
||||
}
|
||||
}
|
||||
request.doc(map);
|
||||
// 在创建UpdateRequest之前加密数据
|
||||
Map<String, Object> encryptedMap = EsDataEncryptUtil.encryptMap(map);
|
||||
|
||||
request.doc(encryptedMap);
|
||||
bulkRequest.add(request);
|
||||
if (bulkRequest.requests().size() >= 1000) {
|
||||
bulk(bulkRequest);
|
||||
|
|
|
|||
Loading…
Reference in New Issue