1.字符串替换

技术原理:通过正则表达式对敏感数据进行部分字符替换

典型代码:

public class StringMasker {  
    // 手机号脱敏:13812345678 → 138****5678  
    public static String maskMobile(String mobile) {  
        return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");  
    }  

    // 身份证脱敏:110101199003077777 → 1101********7777  
    public static String maskIdCard(String idCard) {  
        if (idCard.length() == 18) {  
            return idCard.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2");  
        }  
        return idCard; // 处理15位旧身份证  
    }  
}

使用正则表达式将关键字字段替换成了*

适用场景对比:

优缺点分析

  • ✅ 优点:实现简单、性能高(时间复杂度O(n))
  • ❌ 缺点:
    • 无法恢复原始数据
    • 正则表达式需考虑多国数据格式差异
    • 存在模式被破解风险(如固定位置替换)
2.加密算法

加密算法选型

算法类型代表算法特点适用场景
对称加密AES加解密快,密钥管理复杂支付信息存储
非对称加密RSA速度慢,安全性高密钥交换
国密算法SM4符合国家标准政府/金融系统

代码示例

public class AESEncryptor {  
    privatestaticfinal String ALGORITHM = "AES/GCM/NoPadding";  
    privatestaticfinalint TAG_LENGTH = 128; // 认证标签长度  

    public static String encrypt(String plaintext, SecretKey key) {  
        byte[] iv = newbyte[12]; // GCM推荐12字节IV  
        SecureRandom random = new SecureRandom();  
        random.nextBytes(iv);  

        Cipher cipher = Cipher.getInstance(ALGORITHM);  
        cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(TAG_LENGTH, iv));  

        byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));  
        return Base64.getEncoder().encodeToString(iv) + ":" +  
               Base64.getEncoder().encodeToString(ciphertext);  
    }  

    // 解密方法类似...  
}

密钥管理方案对比

3.数据遮蔽

通过特定的技术手段对敏感数据进行处理,使其在保留数据格式和部分特征的同时,隐藏或替换真实内容。

数据库层实现的数据遮蔽:

CREATE VIEW masked_customers AS  
SELECT  
    id,  
    CONCAT(SUBSTR(name,1,1), '***') AS name,  
    CONCAT(SUBSTR(mobile,1,3), '****', SUBSTR(mobile,8,4)) AS mobile  
FROM customers;  

-- 使用列级权限控制  
GRANT SELECT (id, name, mobile) ON masked_customers TO test_user;

创建数据脱敏视图,在视图中将关键字段做遮蔽。

然后在后面需要用到这些字段的代码,需要统一从视图中查询数据。

代理层实现

rules:  
-!MASK
tables:
    user:
      columns:
        phone:
          maskAlgorithm:phone_mask
maskAlgorithms:
    phone_mask:
      type:MD5
      props:
        salt:abcdefg123456

性能影响测试数据

数据量原始查询(ms)遮蔽查询(ms)性能损耗
10万12014520.8%
100万980115017.3%
1000万105001220016.2%
4.数据替换

将原始数据和脱敏的数据保存到cache中,方便后面快速的做转换。

映射表设计:

// 使用Guava Cache实现LRU缓存  
LoadingCache<String, String> dataMapping = CacheBuilder.newBuilder()  
    .maximumSize(100000)  
    .expireAfterAccess(30, TimeUnit.MINUTES)  
    .build(new CacheLoader<String, String>() {  
        public String load(String key) {  
            return UUID.randomUUID().toString().replace("-", "");  
        }  
    });  

public String replaceData(String original) {  
    return dataMapping.get(original);  
}

替换流程:

5.动态脱敏

应用层实现(Spring AOP示例)





@Aspect  
@Component
publicclass DataMaskAspect {  

    @Around("@annotation(requiresMasking)")  
    public Object maskData(ProceedingJoinPoint joinPoint, RequiresMasking requiresMasking) throws Throwable {  
        Object result = joinPoint.proceed();  
        return mask(result, requiresMasking.type());  
    }  

    private Object mask(Object data, MaskType type) {  
        if (data instanceof User) {  
            User user = (User) data;  
            switch(type) {  
                case MOBILE:  
                    user.setMobile(MaskUtil.maskMobile(user.getMobile()));  
                    break;  
                case ID_CARD:  
                    user.setIdCard(MaskUtil.maskIdCard(user.getIdCard()));  
                    break;  
            }  
        }  
        return data;  
    }  
}

在需要做数据脱敏的字段上技术RequiresMasking注解,然后在Spring的AOP拦截器中,通过工具类动态实现数据的脱敏。

数据库代理层架构

6.K匿名化

通俗解释是

假设医院发布就诊数据:

年龄性别疾病
25感冒
25发烧
25骨折

当K=3时,攻击者无法确定具体某人的疾病,因为3人都具有相同特征(25岁男性)。

实现步骤:

医疗数据泛化示例





public class KAnonymity {  

    // 年龄泛化:精确值→范围  
    public static String generalizeAge(int age) {  
        int range = 10; // K=10  
        int lower = (age / range) * range;  
        int upper = lower + range - 1;  
        return lower + "-" + upper;  
    }  
}

假设range是K值,等于10。

generalizeAge方法中,通过一定的算法,将年龄的精确值,泛化成一个区间范围。

输入年龄28,返回20-29。

K值选择原则

7.总结
方案安全性性能可逆性适用场景
字符串替换24不可逆日志/展示
加密算法42可逆支付信息存储
数据遮蔽33部分可逆数据库查询
数据替换42可逆测试数据生成
动态脱敏43动态可控生产环境查询
k匿名化51不可逆医疗/位置数据