脱敏前必须识别出哪些字段算敏感数据
不是所有字符串都需要脱敏,比如日志里的
StatusCode或
ThreadId就不用动。真正要处理的是身份证号、手机号、银行卡号、邮箱、姓名、地址这些在业务规则里明确定义为 PII(个人身份信息)的字段。
常见错误是直接对整个文件做正则替换,结果把 JSON 的
"id"字段名、XML 的
<id></id>标签名也给替换了,导致格式损坏。必须基于结构化上下文判断——比如只替换 JSON 中 key 为
"phone"、
"idCard"、
"email"对应的 value,而不是全文扫
"1[3-9]\d{9}"。
实操建议:
优先用 JSON Schema 或 XML XSD 定义敏感字段路径,再用JToken.SelectTokens()(Newtonsoft.Json)或
JsonNode.GetProperty()(System.Text.Json)精准定位 如果只有纯文本日志,先按行切分,再用
Regex.Match(line, @"(? 这类带上下文边界的正则,避免误匹配别忘了检查大小写和空格变体:比如
"PHONE"、
" phone "、
"mobile_number"都得覆盖到
用 ReplaceValue 而不是 ReplaceAll,避免破坏嵌套结构
很多开发者习惯用
string.Replace()或
Regex.Replace()全局替换,但面对 JSON 文件时,这会导致引号、逗号、括号被连带污染。比如把
"name":"张三"替成
"name":"***"看似正常,但如果原始值含转义字符
"name":"张\"三",粗暴替换会破坏 JSON 合法性。
正确做法是解析后修改节点值,再序列化回文本。这样能保格式、保编码、保嵌套层级。
实操建议:
JSON 场景下,用JsonDocument.Parse()+
JsonElement.Clone()构建可写副本,遍历中调用
GetProperty()找到目标字段后,用
Utf8JsonWriter写入脱敏值 XML 场景下,用
XDocument加
XPathSelectElements("//user/phone | //order/contact/email") 精准选中,再设 node.Value = MaskPhone(node.Value)纯文本日志若无法结构化解析,至少用
Regex.Replace(line, @"(? MaskIdCard(m.Value)),确保只替换冒号后紧跟的值部分
脱敏算法不能只用星号,要考虑业务可追溯性
简单地把手机号变成
"138****1234"看似安全,但测试环境查问题时,开发可能需要知道“这批数据原本属于哪个省”。全量打星会丢失地域、运营商等低风险特征,反而增加排查成本。
更合理的做法是分级脱敏:高敏感字段(如身份证号)用哈希+盐脱敏;中敏感字段(如手机号)保留前3后4;低敏感字段(如姓名)只掩码中间字。关键是要让脱敏后的数据仍能在内部系统间关联,又不泄露原始值。
实操建议:
身份证号优先用SHA256(Encoding.UTF8.GetBytes(idCard + salt)).Take(8).ToHexString(),比直接截断更抗碰撞 手机号用
phone.Substring(0, 3) + "****" + phone.Substring(7),注意校验长度,防止
"13"这种异常值崩掉 substring 姓名脱敏要区分中文/英文:中文用
name.Length > 2 ? name[0] + "*" + name[^1] : "*",英文用
Regex.Replace(name, @"(?
文件读写过程容易丢编码或锁住文件
生产环境文件常是 GB2312 编码的日志,或者 UTF-8 with BOM 的配置文件。用
File.ReadAllText(path)默认走 UTF-8,一读就乱码,后续脱敏结果全是问号。更糟的是,如果用
File.OpenRead()后没显式
Dispose(),文件句柄一直被占着,下次脚本运行直接抛
IOException: The process cannot access the file。
实操建议:
读文件必须显式指定编码:File.ReadAllText(path, Encoding.GetEncoding("GB2312")) 或先用 File.ReadAllBytes()判断 BOM 再选编码 写文件用
File.WriteAllText(path + ".masked", content, Encoding.UTF8),别覆盖原文件,留备份 大文件(>100MB)别一次性读进内存,改用
StreamReader行读 +
StreamWriter行写,配合
using确保及时释放句柄
最常被忽略的一点:脱敏脚本上线前,一定要在真实编码、真实权限、真实文件锁场景下跑通一次。本地调试用的 UTF-8 小文件,跟生产上 GBK 编码、被 IIS 进程锁定的 2GB 日志,行为完全不同。
