[安全开发]日志敏感信息检测-1-身份证
Posted 白夜鸦羽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[安全开发]日志敏感信息检测-1-身份证相关的知识,希望对你有一定的参考价值。
前言
防止敏感信息泄漏,保护用户和企业信息隐私,是企业安全中重要的环节。
通过检测日志中的敏感信息,能够:
- 排查潜在的泄漏敏感信息的系统和接口,防止被黑产恶意利用,盗取用户敏感信息
- 检查数据传输、日志打印的规范,是否对敏感信息有做加密、脱敏等处理
对于海量日志的敏感信息检测,可以采用Flink流数据处理引擎,进行检测排查。
本文不讨论Flink,只记录日志中身份证号码检测规则的一点心得。
身份证号码格式
一代身份证基本不存在了,无需做检测,一起来看看二代身份证的格式。
二代身份证号码共18位,由17位本体码和1位校验码组成:
- 前6位:地址码,表示登记户口时所在地的行政区划代码
- 7到14位:出生年月日,采用YYYYMMDD格式
- 15到17位:顺序码,同一地区,同一年月日出生的人的顺序编号,男生奇数,女生偶数
- 第18位:校验码,由前17位本体码计算得到
补充说明一下,二代身份证与一代身份证的区别:
- 位数:一代身15位,二代18位
- 出生日期:一代为YYMMDD格式,二代为YYYYMMDD格式
- 校验码:一代无校验码,二代有校验码
正则提取
首先通过正则,进行简单的筛选,从日志中提取疑似身份证号码的数字。
\\W\\d6(19|20)\\d2((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d3[0-9Xx]\\W
正则说明
\\W
:匹配非单词字符,与"[^A-Za-z0-9_]"等效\\d6
:匹配前6位地址码(19|20)\\d2
:匹配年份((0[1-9])|(10|11|12))
:匹配月份((\\[0-2][1-9])|10|20|30|31)
:匹配日期\\d3
:匹配顺序码[0-9Xx]
:匹配校验码
从生产实践的经验来看,日志中大部分变量值,都被符号所包围,例如:
- example?name=shadow&phone=12345678910&……
- “id_card”:“110101199003071938”,“age”:“18”……
而未被符号所包围的变量,绝大部分可能都是误报,例如:
- deptNo=17261101011990030719384324
所以,初期做日志的敏感信息检测时,可以从这些特殊符号入手,用正则\\W
去做匹配,这样能提高不少准确率。后期敏感信息都被揪出来之后,再去掉\\W
,去进行更大范围、更进一步的检测排查。
在上面的正则表达式里,我们对身份证年月日的部分做了简单校验,但我们不能据此就判定,检测出的是身份证号码,因为在海量日志里,正则会匹配到各种巧合的误报。而依靠人工去筛查这些误报,确认风险,是很费时费力的。我们要做的,就是继续要提高身份证号检测的准确率,所以接下来,我们进一步对身份证号的地址码和校验码进行校验。
地址码校验
身份证的前6位地址码是固定的,我们可以取这前6位数字,与地址码库进行匹配,若匹配成功,则进行下一步,校验码的校验。
地址码库搬运:身份证号码前6位地址码
校验码校验
前面说了,身份证最后一位是校验码,由前17位本体码计算得到,具体的计算算法这里不深究,感兴趣的读者,可以参考这篇博客:身份证号码的编码规则及校验
这里我们直接给出,身份证号码校验码的校验算法的Java代码实现:
/**
*
* 18位的二代身份证号码校验码校验
* @param idCardNo 身份证号码
* @return true - 校验通过
* false - 校验不通过
*/
private static boolean idCardNoCheck(String idCardNo)
// 加权因子
int[] w = 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ;
char[] idCardNoArray = idCardNo.toCharArray();
int sum = 0;
for (int i = 0; i < w.length; i++)
sum += Integer.parseInt(String.valueOf(idCardNoArray[i])) * w[i];
// 校验位是X,则表示10
if (idCardNoArray[17] == 'X' || idCardNoArray[17] == 'x')
sum += 10;
else
sum += Integer.parseInt(String.valueOf(idCardNoArray[17]));
// 如果除11模1,则校验通过
return sum % 11 == 1;
优化思考
通过上面的 正则提取+地址码校验+校验码校验 三部曲,从日志中检测出的数字,基本99%是身份证号码,准确率极高。但在海量日志的检测过程中,各种奇葩数据都有,还是会存在1%的误报的。
对于这1%的误报,有两个处理思路:
- 误报为偶然出现,且只出现过一两次,也没有其他类似特征的误报,则直接忽略即可
- 误报具有一定的特征,且多次出现,为同一类误报,则可以提取特征,针对性的制定白名单过滤。白名单推荐采用正则匹配进行过滤
以上是关于[安全开发]日志敏感信息检测-1-身份证的主要内容,如果未能解决你的问题,请参考以下文章
[安全开发]日志敏感信息检测-3-正则合集(手机号邮箱车牌号)
网络安全学习笔记工具篇——GSIL GITHUB敏感信息泄露检测工具