[安全开发]日志敏感信息检测-2-银行卡

Posted 白夜鸦羽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[安全开发]日志敏感信息检测-2-银行卡相关的知识,希望对你有一定的参考价值。

  1. 前言
  2. 银行卡号码格式
  3. 正则提取
  4. 卡bin校验
  5. 校验码校验
  6. 优化思考

前言

接上一篇文章:[安全开发]日志敏感信息检测-1-身份证

银行卡号码格式

银行卡号码由14至19位数字组成,储蓄卡一般是19位、17位和16位,信用卡一般是16位,其中:

  • 前n位:发卡行识别码,用来标识哪个银行发行的卡,在本文中统一简称为“卡bin”
  • 中间位:个人账户标识,由发卡行自己定义,最多12位
  • 末位:校验码,由前面的数字采用Luhn算法计算得出

正则提取

首先通过正则,进行简单的筛选,从日志中提取疑似银行卡号码的数字。

\\W\\d14,19\\W

正则说明

  • \\W:匹配非单词字符,与"[^A-Za-z0-9_]"等效
  • \\d14,19:匹配14至19位数字

宽进:在上面的正则表达式里,我们用了十分宽松的正则来匹配银行卡号码,只要是14至19位的数字,就都匹配上,这样能保证所有疑似银行卡号码的数字都被找出来。
严出:通过上面正则命中的数字误报会很多,但没关系,再对这些数字进行银行码和校验码校验,能过滤掉绝大部分误报,筛选出真正的银行卡号码。

卡bin校验

银行卡卡bin的长度不固定,一般是6位,但也有短至2位,长至12位的。
我们可以将正则命中的数字,从卡bin长度、卡bin值、银行卡长度三个维度,与卡bin库进行对比,三个值都符合的情况下,最后进行校验码的校验。
银行卡卡bin库搬运:银行卡卡bin数据

校验码校验

前面说了,银行卡最后一位是校验码,由银行卡最后一位前面的所有数字计算得到,具体的计算算法这里不深究,感兴趣的读者,可以参考这篇博客:银行卡号的编码规则及校验
这里我们直接给出,银行卡校验码的校验算法的Java代码实现:

/**
 * 银行卡校验码Luhm校验算法,校验成功则为银行卡卡号
 *
 * @param bankCardNo 银行卡号码
 * @return true-校验成功;false-校验失败
 */
public static boolean bankCardNoCheck(String bankCardNo) 
    String num = bankCardNo.substring(0, bankCardNo.length() - 1);
    char[] numArray = num.toCharArray();
    int luhmSum = 0;
    for (int i = numArray.length - 1, j = 0; i >= 0; i--, j++) 
        int k = numArray[i] - '0';
        if (j % 2 == 0) 
            k *= 2;
            k = k / 10 + k % 10;
        
        luhmSum += k;
    
    char checkNo = (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    return bankCardNo.charAt(bankCardNo.length() - 1) == checkNo;

优化思考

通过上面的 正则提取+卡bin校验+校验码校验 三部曲,从日志中检测出的数字,基本99%是银行卡号码,准确率极高。但在海量日志的检测过程中,各种奇葩数据都有,还是会存在1%的误报的。

对于这1%的误报,有两个处理思路:

  1. 误报为偶然出现,且只出现过一两次,也没有其他类似特征的误报,则直接忽略即可
  2. 误报具有一定的特征,且多次出现,为同一类误报,则可以提取特征,针对性的制定白名单过滤。白名单推荐采用正则匹配进行过滤

以上是关于[安全开发]日志敏感信息检测-2-银行卡的主要内容,如果未能解决你的问题,请参考以下文章

[安全开发]日志敏感信息检测-1-身份证

常见开发场景安全开发指南

银行应用系统日志文件敏感信息脱敏处理方法

[安全开发]敏感信息脱敏函数

网络安全学习笔记工具篇——GSIL GITHUB敏感信息泄露检测工具

环氧树脂绝艳子气泡无损检测