使用mask函数进行数据脱敏

更新时间:
复制 MD 格式

阿里云日志服务(SLS)推出 mask 脱敏函数。相比传统正则脱敏方案的局限性,mask 函数在适用场景上更具优势,并结合典型场景展示其在敏感数据保护与合规要求中的价值。

使用限制

目前mask函数仅适用于数据加工(新版)和写入处理器。

脱敏方案概述

背景

随着AI时代交互数据的快速增长,个人隐私信息的安全保护成为企业合规经营的重要组成部分。GDPR、《数据安全法》、《个人信息保护法》等法律法规对企业处理敏感信息提出了严格要求。

正则脱敏

阿里云日志服务(SLS)提供了一套完善的数据脱敏体系,支持多种灵活的采集+脱敏Pipeline组合流程,以满足不同业务场景的需求。具体操作请参见云上数据安全保护:敏感日志扫描与脱敏实践详解。

  • LoongCollector端侧脱敏:

    • 通过在采集配置中配置数据脱敏插件,利用正则匹配实现对敏感字段的替换。

    • 通过SPL语句使用regexp_replace函数,在服务侧完成高性能脱敏处理。

  • LoongCollector/SDK + 写入处理器联合脱敏:

脱敏升级方案:mask函数

针对正则表达式脱敏存在的配置复杂、性能瓶颈和场景适配难等问题,SLS推出全新的mask脱敏函数,以提供更便捷、高效和智能的数据脱敏解决方案。

mask函数

函数语法

mask(field, varchar params)

参数说明

参数

说明

field

需要脱敏数据的原始字段名称。

param

该参数是JSON数组,可以定义一条或多条param参数规则。

param参数规则

参数

是否必填

说明

mode

是

选择脱敏模式:

  • keyword:关键字匹配,智能识别任意文本中符合"key":"value"、'key':'value'或key=value等常见KV对格式的敏感信息。

  • buildin:内置规则匹配。

  • semantic:语义识别,在服务端启用模型识别中文自然语言中的姓名、地址。目前仅特定地域支持。

types

mode选择buildin 模式必填;semantic 模式通过该参数指定语义类型

内置规则列表:

  • PHONE:匹配中国内地手机号(11位数字,通常以 13/15/17/18/19 开头)。例如13812345678、+8613812345678或者(+86)13812345678

  • IDCARD:匹配中国内地身份证号(18位数字+字母,包含行政区划代码、出生日期、顺序码等)。

  • LANDLINE_PHONE:匹配中国内地固定电话号码。

    • 形态:中国内地固话。

    • 规则: 区号 2-4 位且首位为 0;支持 (010)- 或 010-;本地号 7-8 位;如(010)12345678 010-1234567

  • CREDIT_CARD:匹配信用卡/借记卡号(16-19位数字,支持 Visa=4, MC=51-55/2221-2720, Amex=34/37, Discover=6011/65, UnionPay=62 支持当前几种格式)。

  • IP_ADDRESS:匹配 IPv4 地址(格式:xxx.xxx.xxx.xxx)。

  • EMAIL:匹配标准电子邮件地址。

    • 形态:local-part@domain.tld。

    • 规则: local 支持字母数字、下划线、连字符和点;必须有且仅一个 @;domain 允许字母数字与连字符,必须包含点,末尾 TLD 至少 2 字符。

  • IMSI:移动通信订阅标识。

  • VIN:17 位车辆识别代号,按内置格式及校验规则识别。

  • LICENSE_PLATE:中国内地车牌。

  • ACCESSKEY:阿里云 LTAI 前缀的 AccessKey ID。

  • API_KEY:符合内置规则的 sk-、GitHub Token 格式。

其中 PHONE、IDCARD、IMSI 可通过 regions 选择地域规则,各类型的识别对象及地域支持情况见下方“内置类型与地域范围”。

semantic 模式的语义类型为 NAME(中文姓名)、ADDRESS(地址)。

keys

mode选择keyword模式必填

定义需匹配的关键字列表,如 ["userName", "wallet"]。

regions

否

选择内置地域规则,仅对 PHONE、IDCARD、IMSI 生效,例如 ["DE","GB"]。不填时默认 CN。支持的地域代码见下方地域矩阵。

maskChar

否

用于脱敏的字符,默认为 *。用于默认字符打码及锚点打码。

keepPrefix

否

默认字符打码时保留字段开头的字符数,默认为 0,例如 keepPrefix:3 保留前3位字符。

keepSuffix

否

默认字符打码时保留字段结尾的字符数,默认为 0,例如 keepSuffix:3 保留后3位字符。

maskType

否

脱敏方式:

  • 省略时按字符打码:使用 maskChar 替换,可配合 keepPrefix、keepSuffix 保留前后字符。

  • placeholder:替换为占位符,例如 [VIN_MASKED]、[PHONE_MASKED]。

  • anchor:按锚点打码,配合 maskBeforeChar 使用。

maskBeforeChar

否

配合 maskType 为 anchor 时使用,指定锚点字符,替换该字符之前的内容。例如设为 @ 时替换邮箱用户名,保留 @ 及域名。

prependPlaceholder

否

布尔值,默认 false。设为 true 时,在字符打码或锚点打码结果外添加类型标记,通常输出 [TYPE_MASKED]{脱敏预览},便于查询和审计时识别已处理的信息类别。例如手机号保留前三后四:13600007890 → [PHONE_MASKED]{136****7890};未开启时为 136****7890。

说明

前后保留位数只用于默认字符打码,anchor 使用锚点参数,placeholder 使用占位符。

内置类型与地域范围

types

识别对象

regions 支持情况

PHONE

手机号

支持,见下方地域矩阵

IDCARD

身份证或个人身份识别号码

支持,见下方地域矩阵

IMSI

移动通信订阅标识

支持,见下方地域矩阵

VIN

17 位车辆识别代号

不支持地域切换,按内置格式及校验规则识别

LICENSE_PLATE

中国内地车牌

不支持地域切换,仅中国内地规则

LANDLINE_PHONE

中国内地固定电话

不支持地域切换,仅中国内地规则

EMAIL

邮箱地址

不按地域选择规则

CREDIT_CARD

银行卡号

不按地域选择规则,需符合内置格式及校验规则

IP_ADDRESS

IPv4 地址

不按地域选择规则

ACCESSKEY

阿里云 LTAI 前缀的 AccessKey ID

不按地域选择规则

API_KEY

符合内置规则的 sk-、GitHub Token 格式

不按地域选择规则

只有 PHONE、IDCARD、IMSI 支持地域切换,下表中“—”表示当前无对应内置规则。

regions 代码

国家或地区

PHONE

IDCARD

IMSI

CN

中国内地

支持

支持

支持

HK

中国香港

支持

支持

支持

DE

德国

支持

—

支持

GB

英国

支持

—

支持

AE

阿联酋

支持

—

支持

SA

沙特阿拉伯

支持

—

支持

SG

新加坡

支持

—

支持

KZ

哈萨克斯坦

支持

支持

—

UZ

乌兹别克斯坦

支持

支持

—

RU

俄罗斯

支持

—

—

示例

示例1:交易数据脱敏

DeFi平台每日处理数万笔链上交易,每笔交易都会生成包含用户钱包地址、交易哈希、用户画像等敏感信息的详细日志。为了满足数据保护法规要求,同时保证业务分析和故障排查的需要,需要对交易确认日志中的钱包地址、地址信息、来源IP、手机号、交易哈希等敏感字段进行脱敏,保留前后各3位字符以便业务追溯。

  • 原始数据

    2025-08-20 18:04:40,998 INFO  blockchain-event-poller-3 [10.0.1.20] [com.service.listener.TransactionStatusListener:65] [TransactionStatusListener#handleSuccessfulTransaction]{"message":"On-chain transaction successfully confirmed","confirmationDetails":{"transactionHash":"0x2baf892e9a164b1979","status":"success","blockNumber":45101239,"gasUsed":189543,"effectiveGasPrice":"58.2 Gwei","userProfileSnapshot":{"wallet":"0x71C7656EC7a5f6d8A7C4","sourceIp":"203.0.113.55","phone":"19901012345","address":"上海市浦东新区文明路1000号","birthday":null}}}
  • SPL语句

    在数据处理器中使用以下SPL语句。

    *| extend content =  mask(content,'[
               {"mode":"keyword","keys":["wallet","address","sourceIp","phone","transactionHash"], "maskChar":"*","keepPrefix":3,"keepSuffix":3}
             ]')
  • 输出结果

    2025-08-20 18:04: 40, 998 INFO blockchain-event-poller-3 [10.0.1.20][com.service.listener.TransactionStatusListener: 65]][TransactionStatusListener#handleSuccessfulTransaction]{"message": "0n-chain transaction successfully confirmed", "confirmationDetails": {"transactionHash": "0×2**************979", "status": "success", "blockNumber": 45101239, "gasUsed": 189543, "effectiveGasPrice": "58.2 Gwei", "userProfileSnapshot": {"wallet": "0x7****************7C4", "sourceIp": "203******.55", "phone": "199*****345", "address": "上海市*********00号", "birthday": null}}}

示例2:Nginx日志中敏感URI参数脱敏实践

某电商平台的API网关每日处理数千万次请求,现需要对URI里的uid和token参数进行脱敏,保留前后各2位字符。

  • 原始数据

    这是一条典型的API访问日志URI,包含了用户身份信息和会话认证信息。

    http_protocol: HTTP/1.1
    remote_addrs: 127.0.0.1
    request_time:  5000
    status: 302
    time_local: 2025-08-19T18:52:03+08:00
    uri: "uid=user12345&token=bf81639a41d604&from=web"
    user_agent: Mozilla/5.0(Windows NT 5.2; WOW64))AppleWebKit/535.1(
    (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1
  • SPL语句

    在数据处理器中使用keyword模式,定位URI参数进行选择性脱敏。

    * | extend uri=mask(uri, '[
    {"mode": "keyword", "keys": ["uid", "loginIp", "token"],  "maskChar": "*", "keepPrefix": 2, "keepSuffix": 2}
    ]')
  • 输出结果

    http_protocol: HTTP/1.1
    remote_addrs: 127.0.0.1
    request_time:  5000
    status: 302
    time_local: 2025-08-19T18:52:03+08:00
    uri: uid=us*****45&token=bf**********04&from=web
    user_agent: Mozilla/5.0(Windows NT 5.2; WOW64))AppleWebKit/535.1(
    (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1

示例3:大模型交互日志脱敏

智能客服平台每日处理超过10万次用户咨询,用户经常在求助时无意中透露手机号、身份证、银行卡等敏感信息。需要自动识别并脱敏用户输入中的手机号、邮箱、IP地址、身份证号和信用卡号等敏感信息,在保护隐私的同时保留语义完整性,为后续的AI训练和分析提供安全、可用的数据。

  • 原始数据

    这是一条用户向AI客服求助的完整对话记录,包含了几乎所有常见的PII类型。

    你好,我需要紧急帮助!我是你们平台的长期付费用户,我的账户好像被锁定了,而且一笔年度会员续费失败了。我非常着急,因为我今晚需要使用你们的高级功能来完成一个项目
    以下是我的全部信息,请你们的系统管理员或技术支持立刻为我核实并解决问题:
    姓名张伟
    注册手机号是19901012345
    注册邮箱是 zhangwei.service@example.com
    我最近一次登录的IP地址 203.0.113.55
    身份证号是 110105199003070033
    用于支付的信用卡信息如下:
    信用卡类型 Visa
    卡号是 4539-1488-0343-6467
    持卡人姓名 ZHANG WEI
    有效期 12/25
    CVV码 123
    请尽快处理,万分感谢!我真的非常需要你们的帮助!
  • SPL语句

    • SPL配置:使用buildin模式,智能识别多种敏感信息类型。

    • 配置说明:

      • 第一条规则:对IP地址和邮箱进行完全脱敏(默认用*全部替换)。

      • 第二条规则:对手机号、身份证号、信用卡号进行部分脱敏,保留前3位后4位。

    * | extend content =  mask(content,'[
                 {"mode":"buildin","types":["IP_ADDRESS","EMAIL","LANDLINE_PHONE"]},
                 {"mode":"buildin","types":["PHONE","IDCARD","CREDIT_CARD"], "maskChar":"*","keepPrefix":3,"keepSuffix":4}
                ]')
  • 输出结果

    content:你好,我需要紧急帮助!我是你们平台的长期付费用户,我的账户好像被锁定了,而且一笔年度会员续费失败了。我非常着急,因为我今晚需要使用你们的高级功能来完成一个项目
    以下是我的全部信息,请你们的系统管理员或技术支持立刻为我核实并解决问题:
    姓名张伟
    注册手机号是199****2345
    注册邮箱是****************************
    我最近一次登录的IP地址 ************
    身份证号是110***********0033
    用于支付的信用卡信息如下:
    信用卡类型 Visa
    卡号是453************6467
    持卡人姓名 ZHANG WEI
    有效期12/25
    CVV码123
    请尽快处理,万分感谢!我真的非常需要你们的帮助!

本文日志及个人信息均为构造示例。

示例4:车联网事件处理日志脱敏

车辆信号经消息队列进入规则计算和云端诊断服务,事件日志会记录 VIN、软件版本、信号值与规则结果。同一 VIN 可能同时出现在事件头和嵌套载荷中,规则需要覆盖正文里的每一处匹配。以下冷却液温度评估日志中,两处 VIN 使用占位符,车牌保留前两位,接口 token 按业务键替换。配置对整个 content 执行识别。

  • 原始数据

    {
      "time": "2026-10-13T09:18:42.036+08:00",
      "level": "INFO",
      "service": "vehicle-event-processor",
      "trace_id": "demo-event-a201",
      "event": "vehicle_signal_evaluated",
      "vin": "LZZAB12C7T1006842",
      "plate_no": "粤B24680",
      "payload": {
        "vin": "LZZAB12C7T1006842",
        "signal": "coolant_temperature",
        "value": 94,
        "rule_id": "coolant_temp_guard",
        "rule_version": "r12",
        "decision": "NORMAL"
      },
      "software_version": "5.4.0",
      "mq": {
        "topic": "vehicle.signal.events",
        "partition": 3,
        "offset": 873204
      },
      "latency_ms": 21,
      "token": "demo_vehicle_token_82"
    }
  • SPL语句

    在写入处理器中使用以下SPL语句。

    * | extend content = mask(content, '[
      {"mode":"buildin","types":["VIN"],"maskType":"placeholder"},
      {"mode":"buildin","types":["LICENSE_PLATE"],"keepPrefix":2},
      {"mode":"keyword","keys":["token"],"maskType":"placeholder"}
    ]')
  • 输出结果

    外层 vin 和 payload.vin 均变为 [VIN_MASKED],车牌变为 粤B*****,token 替换为关键词占位符。信号值 94、判定 NORMAL、规则版本 r12 与软件版本 5.4.0 保持原值,可继续核对事件内容与版本;mq.offset 保留消费位点,latency_ms 保留处理耗时。

    说明

    内置 VIN 识别包含格式与校验条件,异常格式的车辆标识可按已知键补充处理。需要跨日志追踪事件时,应选用经过评估的事件 ID 或 Trace ID;占位符及部分打码的车辆标识无法承担唯一关联键的作用。

示例5:车主实名认证与车辆绑定日志脱敏

用户中心日志记录车主实名认证和车辆绑定的请求。身份信息可能出现在请求参数中,用户标识则可能同时出现在请求和数据库查询上下文中。检查这类接口时,需要隐藏个人信息,并保留核验结果和绑定状态。owner_name、user_id 使用关键词占位符,中国内地手机号保留前三后四,身份证号完全替换。

  • 原始数据

    2026-10-13 09:24:16.218 INFO [owner-identity-service] trace_id=demo-owner-b018 uri=/api/owners/bind method=POST cost_ms=38 status=200
    {
      "request": {
        "owner_name": "陈宁",
        "phone": "13900004567",
        "id_card": "320104199408190028",
        "user_id": "owner-demo-018"
      },
      "response": {
        "verification": "PASS",
        "binding_status": "SUCCESS",
        "code": "OK"
      },
      "query": {
        "mapper": "OwnerBindingRepository.findByUser",
        "user_id": "owner-demo-018"
      }
    }
  • SPL语句

    在写入处理器中使用以下SPL语句。

    * | extend content = mask(content, '[
      {"mode":"buildin","types":["PHONE"],"keepPrefix":3,"keepSuffix":4},
      {"mode":"buildin","types":["IDCARD"],"maskType":"placeholder"},
      {"mode":"keyword","keys":["owner_name","user_id"],"maskType":"placeholder"}
    ]')
  • 输出结果

    请求和查询中的两处 user_id 都被替换,姓名和完整身份证号不再出现在正文中,手机号保留前三后四。verification=PASS、binding_status=SUCCESS 和 code=OK 保留,可确认请求已通过核验并完成绑定;日志头中的接口路径、Trace ID 和 38 毫秒耗时也保持原值。用户标识以字符串记录,替换后 JSON 正文仍可解析。

    说明

    keyword 配置需包含实际键名,例如 owner_name、userName 等命名应分别核对。不需要人工核对号码的业务可改用占位符;处理范围还应检查请求、响应及查询上下文中的重复信息。

示例6:海外联网订阅状态查询日志脱敏

车辆的 T-Box 或通信模块通过 SIM、eSIM 接入移动网络。连接管理平台查询订阅状态和流量额度时,运营商接口可能返回 IMSI(国际移动用户识别码),它标识通信订阅,也应纳入脱敏范围。以下德国、英国两条订阅记录使用 regions=["DE","GB"] 识别手机号与 IMSI;邮箱隐藏 @ 前的本地部分;运营商接口 token 使用关键词规则。

  • 原始数据

    2026-10-13 09:41:22.075 INFO [connectivity-subscription-service] trace_id=demo-connect-d005 uri=/api/subscriptions/status method=GET cost_ms=34 status=200
    {
      "code": "OK",
      "subscriptions": [
        {
          "market": "DE",
          "phone": "+4915700002468",
          "imsi": "262010000345678",
          "email": "driver.de@example.com",
          "sim_status": "ACTIVE",
          "connection_status": "CONNECTED",
          "quota_mb": 4096
        },
        {
          "market": "GB",
          "phone": "+447700900123",
          "imsi": "234100000456789",
          "email": "driver.gb@example.com",
          "sim_status": "ACTIVE",
          "connection_status": "CONNECTED",
          "quota_mb": 2048
        }
      ],
      "token": "demo_subscription_token_05"
    }
  • SPL语句

    在写入处理器中使用以下SPL语句。

    * | extend content = mask(content, '[
      {"mode":"buildin","types":["PHONE","IMSI"],"regions":["DE","GB"],"maskType":"placeholder"},
      {"mode":"buildin","types":["EMAIL"],"maskType":"anchor","maskBeforeChar":"@"},
      {"mode":"keyword","keys":["token"],"maskType":"placeholder"}
    ]')
  • 输出结果

    手机号输出 [PHONE_MASKED],IMSI 输出 [IMSI_MASKED];邮箱使用 anchor 隐藏 @ 前的部分并保留域名;token 输出关键词占位符。两条记录的市场、sim_status=ACTIVE、connection_status=CONNECTED 及流量额度(4096 MB、2048 MB)保持原值。

    说明

    regions 选择的是识别规则,车辆销售地不一定等于号码或 IMSI 的归属网络,跨境连接方案需核对实际号码。德国、英国的手机号与 IMSI 支持,不代表所有欧洲国家、证件和车牌类型均已覆盖,支持范围见“内置类型与地域范围”。

示例7:座舱语音指令与大模型调用日志脱敏

座舱将语音转写文本交给意图识别或大模型,再调用通讯录、导航等工具。同一姓名和目的地可能在转写文本、工具返回与模型回复中重复出现。以下通话与导航组合指令中,使用 semantic 模式识别中文姓名、地址,buildin 处理手机号和符合支持特征的 API Key,keyword 处理自定义凭证键;模型名称、意图、工具状态和耗时保留。semantic 模式目前仅特定地域支持。

  • 原始数据

    {
      "time": "2026-10-13T09:48:30.906+08:00",
      "service": "cockpit-assistant-gateway",
      "session_id": "session-demo-047",
      "trace_id": "demo-cockpit-e047",
      "model": "cockpit-text-model",
      "intent": "NAVIGATE_AND_CALL",
      "asr_text": "请给林晨打电话,号码是13600007890,然后导航到杭州市西湖区示例路28号。",
      "tool_calls": [
        {
          "name": "contacts.lookup",
          "result_text": "联系人林晨,联系电话13600007890。",
          "status": "SUCCESS"
        },
        {
          "name": "navigation.search",
          "result_text": "目的地为杭州市西湖区示例路28号。",
          "status": "SUCCESS"
        }
      ],
      "assistant_text": "已找到林晨,将导航至杭州市西湖区示例路28号。",
      "llm_api_key": "sk-DemoCockpitKeyAbcdef0123456789",
      "input_tokens": 96,
      "output_tokens": 27,
      "cost_ms": 463
    }
  • SPL语句

    在写入处理器中使用以下SPL语句。

    * | extend content = mask(content, '[
      {"mode":"semantic","types":["NAME","ADDRESS"],"maskType":"placeholder"},
      {"mode":"buildin","types":["PHONE","API_KEY"],"maskType":"placeholder"},
      {"mode":"keyword","keys":["token","api_key"],"maskType":"placeholder"}
    ]')
  • 输出结果

    asr_text、两个 result_text 和 assistant_text 中的姓名、地址均按实体位置替换,手机号和 API Key 也被隐藏。模型名称、意图 NAVIGATE_AND_CALL、两个工具的 SUCCESS 状态、输入输出 Token 数及 463 毫秒总耗时保留。

示例8:使用类型标记与脱敏预览

在自然语言和混合文本日志中,打码后仍可能需要区分手机号、凭证等信息类型,并保留必要的核对线索。prependPlaceholder:true 可在字符打码或锚点打码结果外添加类型标记,通常输出 [TYPE_MASKED]{脱敏预览}。以示例7的日志为例,姓名、地址继续使用占位符完全替换;手机号和 API Key 保留前三后四,并附加类型标记。

  • SPL语句

    在写入处理器中使用以下SPL语句。

    * | extend content = mask(content, '[
      {"mode":"semantic","types":["NAME","ADDRESS"],"maskType":"placeholder"},
      {"mode":"buildin","types":["PHONE","API_KEY"],"keepPrefix":3,"keepSuffix":4,"prependPlaceholder":true},
      {"mode":"keyword","keys":["token","api_key"],"keepPrefix":3,"keepSuffix":4,"prependPlaceholder":true}
    ]')
  • 输出结果

    手机号输出为 [PHONE_MASKED]{136****7890},可通过 [PHONE_MASKED] 判断这是已脱敏的手机号,用保留的前后缀辅助核对调用对象,再通过 trace_id 关联调用链路。保留位数应按排障需要选择。该参数也适用于姓名、地址等类型,例如语义规则识别到“林晨”时,设置 keepPrefix: 1 和 prependPlaceholder: true,可输出 [NAME_MASKED]{林*}。