Skip to content

数据脱敏

TIP

对 Vo 等 JSON 输出 字段使用 @SensitivityEncrypt,由 SensitivitySerializer 在 Jackson 序列化时按类型做掩码;仅影响序列化结果,不等同于数据库加密存储。

注解

  • 定义:com.sxpcwlkj.common.annotation.SensitivityEncrypt
  • 配合:@JsonSerialize(通过 @JacksonAnnotationsInside 已内置)
java
import com.sxpcwlkj.common.annotation.SensitivityEncrypt;
import com.sxpcwlkj.common.enums.SensitivityTypeEnum;

// 手机号
@SensitivityEncrypt(type = SensitivityTypeEnum.PHONE)
private String phoneNumber;

类型枚举 SensitivityTypeEnum

  • 完整类名com.sxpcwlkj.common.enums.SensitivityTypeEnum
  • 模块mms-modules/mms-common
  • 声明方式public enum,带 Lombok @Getter(仅为枚举常规 getter;本枚举无附加字段,故与默认 name() / ordinal() 并存)。

当前源码中下列 5 个枚举常量(依 Java 声明顺序ordinal()0~4)。若本地工程已新增常量,以仓库实际文件为准。

源码全文(与仓库一致)

以下为 SensitivityTypeEnum.java镜像(包名、import、类注释、常量注释与主仓一致),便于对照与检索。

java
package com.sxpcwlkj.common.enums;

import lombok.Getter;

/**
 * 脱敏
 * @author: mmsAdmin
 * @date: 2020/11/17 14:44
 * @description:
 */
@Getter
public enum SensitivityTypeEnum {

    /**
     * 姓名
     */
    NAME,

    /**
     * 身份证号
     */
    ID_CARD,

    /**
     * 邮箱
     */
    EMAIL,

    /**
     * 手机号
     */
    PHONE,

    /**
     *  自定义(此项需设置脱敏的前置后置长度)
     */
    CUSTOMER,
}

常量一览(写全)

ordinal()枚举常量字段注释(源码)SensitivitySerializer 分支SensitivityUtil 方法规则摘要(与实现一致)
0NAME姓名case NAMEhideChineseName内部调用 desValue(origin, 1, 0, "*")仅首字符明文,其后每位为 *
1ID_CARD身份证号case ID_CARDhideIDCard正则替换:(\\d{4})\\d{10}(\\w{4})$1*****$2,即 前 4 + 中间 5 位 * + 后 4(按 18 位大陆身份证 形态设计,其它证件勿直接套用)
2EMAIL邮箱case EMAILhideEmail正则:(\\w?)(\\w+)(\\w)(@\\w+\\.[a-z]+(\\.[a-z]+)?)$1****$3$4,即 首字符 + **** + @ 前末字符 + 域名
3PHONE手机号case PHONEhidePhone正则:(\\d{3})\\d{4}(\\d{4})$1****$2,即 前 3 + **** + 后 411 位手机号形态)
4CUSTOMER自定义(此项需设置脱敏的前置后置长度)case CUSTOMERdesValue使用 @SensitivityEncryptprefixNoMaskLensuffixNoMaskLensymbol 调用 desValue;中间段逐字符替换为 symbol

未覆盖值SensitivitySerializerswitch 对以上 5 类穷举;若传入扩展枚举却未改切面,会落入 defaultIllegalArgumentException(源码:unknown privacy type enum)。

@SensitivityEncrypt 的关系

  • CUSTOMER:仅 type 生效,固定走对应 SensitivityUtil 方法。
  • CUSTOMER:除 type 外必须使用 prefixNoMaskLen / suffixNoMaskLen / symbol(注解带默认值,与文档「自定义掩码」章节一致)。

相关类:SensitivityTypeEnumSensitivitySerializerSensitivityUtilSensitivityEncrypt


按场景的用法说明

下列为常见脱敏需求与推荐做法。除内置枚举已覆盖的类型外,多数可用 CUSTOMER 按「前后保留字符数」近似实现;规则复杂(正则、分段、多分隔符)时,建议在 SensitivityUtil 增加专用方法并在 SensitivitySerializer 中扩展 switch 分支,避免注释写很长却仍难调参。

银行卡号

  • 展示习惯:常保留 前 4 位 + 后 4 位,中间打星;卡号长度多为 16~19 位(以实际卡 BIN 与发卡行为准)。
  • 注解示例type = CUSTOMERprefixNoMaskLen = 4suffixNoMaskLen = 4symbol = "*"
  • 注意:需符合支付合规时,接口侧可能直接 不返回 完整卡号,仅返回掩码或 token,不止 JSON 脱敏一层。

地址(省 / 市 / 区 + 门牌)

  • 推荐:库表或 Vo 拆分「省市区」与「详细地址」字段;省市区可原样或轻度脱敏详细门牌、楼栋室号单独字段做 CUSTOMER 或高强度掩码。
  • 若仅为一条长字符串:只能按字符估算,prefixNoMaskLen 取省市区大致字数,剩余中间一律掩码;准确性不如结构化字段。

IP / MAC

  • IPv4:例如保留 前两段(如 192.168.x.x),可按字符串数到第二段结束位置设 prefixNoMaskLen(需按实际 x.x.x.x 长度数点,没有统一魔法数字);或扩展工具方法按 . 分段处理更稳妥。
  • MAC:习惯保留 首段或首尾若干字符(如 AA:**:**:**:**:BB),可用 CUSTOMER 设前后保留长度,或专用工具按 : 分段。
  • 说明:IP/MAC 多用于审计、风控;对外接口是否返回全量请以安全策略为准。

护照、港澳通行证等证件号

  • 与身份证区别:内置 ID_CARD 对应 hideIDCard18 位大陆身份证规则,不宜直接套在护照号、港澳通行证号上(长度、字母数字组合各异)。
  • 做法:优先 CUSTOMER(前后各保留少量字符);若项目内证件类型固定,可 新增枚举 + SensitivityUtil 方法 + SensitivitySerializer 分支,与身份证并列维护。

车牌号

  • 展示习惯:常保留 地区发牌代号(汉字 + 字母)及 末位 等,中间掩码;新能源与普通车牌长度不同。
  • 做法:按字符串长度调 CUSTOMER 的前后保留位;规则稳定时建议 专用工具方法,避免魔法数字散落在各 Vo。

微信 / 支付宝等账号展示名

  • 习惯首尾少量字可见,中间 *(与昵称长度相关)。
  • 做法:短昵称可用 CUSTOMER(如首尾各 1);较长可用 prefixNoMaskLen = 1suffixNoMaskLen = 1symbol = "*",效果接近「中间打星」。

密码类字段(与「序列化脱敏」不同)

  • 登录密码、支付密码、口令、Token 原文等:接口响应与日志中通常不应出现明文
  • 常见手段
    • Vo / DTO 不包含该字段,或对出参 DTO 使用 @JsonIgnore不序列化
    • 日志中使用 SensitiveOps 或统一占位 ******,而不是依赖 @SensitivityEncrypt 做「美化展示」;
    • 存储侧使用哈希 / 加密由安全方案单独设计。
  • 小结@SensitivityEncrypt 面向「仍需露出部分信息的可读字段」;密码类属于 禁止输出或固定占位,归 接口设计、日志、存储 另一类处理。

自定义掩码(CUSTOMER

CUSTOMERSensitivityUtil.desValue:对字符串从左到右,前 prefixNoMaskLen、后 suffixNoMaskLen 个字符保留,中间每个字符替换为 symbol(默认一个 * 占一位)。

属性说明默认
prefixNoMaskLen前缀不脱敏长度1
suffixNoMaskLen后缀不脱敏长度1
symbol掩码字符*
java
@SensitivityEncrypt(
    type = SensitivityTypeEnum.CUSTOMER,
    prefixNoMaskLen = 4,
    suffixNoMaskLen = 4,
    symbol = "*"
)
private String bankCardNo;

Excel 与日志

  • Excel 导出等场景若需脱敏,可能使用 SensitivitySerializer 之外的 SensitiveOps 工具方法或导出模板配置,以具体导出代码为准。
  • 空值:当前 SensitivitySerializer原始值为 null、空串或未识别类型 等分支下会写出 空字符串 ""(以源码为准);若需 null 不回传,请在 Vo 层或全局序列化策略另行约定。

Released under the MIT License.