
Java+MySQL 数据脱敏实现方案
数据脱敏是保护用户隐私信息的关键技术,尤其在处理姓名、身份证号、手机号等敏感数据时,需遵循 GDPR、CCPA 等隐私法规。以下是基于 Java 和 MySQL 的完整实现方案。
数据库层脱敏设计
MySQL 函数脱敏
CREATE FUNCTION mask_string(input VARCHAR(255), prefix_len INT, suffix_len INT)
RETURNS VARCHAR(255)
BEGIN
DECLARE masked VARCHAR(255);
SET masked = CONCAT(
LEFT(input, prefix_len),
REPEAT('*', LENGTH(input) - prefix_len - suffix_len),
RIGHT(input, suffix_len)
);
RETURN masked;
END;
敏感字段标记
ALTER TABLE users
ADD COLUMN is_sensitive BOOLEAN DEFAULT FALSE,
COMMENT '标记字段是否需要脱敏处理';
Java 应用层实现
注解驱动脱敏
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SensitiveData {
String maskPattern() default "\\w(?=\\w{4})";
String replacement() default "*";
}
AOP 切面处理
@Aspect
@Component
public class DataMaskingAspect {
@Around("@annotation(com.example.MaskingRequired)")
public Object applyMasking(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
if (result instanceof Collection) {
((Collection<?>) result).forEach(this::maskFields);
} else {
maskFields(result);
}
return result;
}
}
动态脱敏策略
策略模式实现
public interface MaskingStrategy {
String mask(String input);
}
public class PhoneMasking implements MaskingStrategy {
@Override
public String mask(String phone) {
return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
}
}
策略上下文
public class MaskingContext {
private static final Map<DataType, MaskingStrategy> strategies = Map.of(
DataType.PHONE, new PhoneMasking(),
DataType.ID_CARD, new IdCardMasking()
);
public static String execute(DataType type, String input) {
return strategies.get(type).mask(input);
}
}
审计与权限控制
Spring Security 集成
@PreAuthorize("hasRole('ADMIN') || #userId == principal.id")
@GetMapping("/users/{userId}")
public UserDTO getUser(@PathVariable Long userId) {
User user = userService.findById(userId);
return maskingService.apply(user);
}
脱敏日志记录
@Aspect
@Component
public class LogMaskingAspect {
@Around("execution(* com.example..*.*(..))")
public Object maskLogs(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = Arrays.stream(pjp.getArgs())
.map(arg -> MaskingUtils.maskSensitiveFields(arg))
.toArray();
return pjp.proceed(args);
}
}
性能优化方案
缓存脱敏结果
@Cacheable(value = "maskedUsers", key = "#userId")
public UserDTO getMaskedUser(Long userId) {
User user = userRepository.findById(userId);
return maskingService.apply(user);
}
批量处理优化
public List<UserDTO> batchMaskUsers(List<Long> ids) {
return jdbcTemplate.query(
"SELECT * FROM users WHERE id IN (:ids)",
new MapSqlParameterSource("ids", ids),
(rs, rowNum) -> {
User user = new User();
user.setPhone(rs.getString("phone"));
return maskingService.apply(user);
}
);
}
合规性检查
正则表达式验证
public boolean isCompliant(String input, DataType type) {
Pattern pattern = Pattern.compile(type.getValidationRegex());
return pattern.matcher(input).matches();
}
数据水印追踪
public String addWatermark(String original) {
String watermark = UUID.randomUUID().toString().substring(0,8);
return original + "_W_" + watermark;
}
以上方案实现需注意:
- 根据业务需求调整脱敏粒度
- 测试环境保留原始数据与脱敏数据的映射关系
- 定期审计脱敏规则的有效性
- 敏感数据访问需保留完整操作日志
959

被折叠的 条评论
为什么被折叠?



