IMS系统数据脱敏完全指南

数据脱敏是对敏感数据进行变形处理,在保留数据特征的同时保护隐私信息。本文详细介绍 IMS 系统中的数据脱敏策略与实现方案,满足等保和合规要求。

脱敏字段分类

识别并分类需要脱敏的敏感字段:

/* 敏感字段配置 */
const SENSITIVE_FIELDS = {
    /* 个人信息 */
    'name': { type: 'name', level: 'medium' },
    'phone': { type: 'phone', level: 'high' },
    'id_card': { type: 'id_card', level: 'high' },
    'email': { type: 'email', level: 'medium' },
    'address': { type: 'address', level: 'medium' },
    'birthday': { type: 'date', level: 'low' },

    /* 金融信息 */
    'bank_card': { type: 'bank_card', level: 'high' },
    'account': { type: 'account', level: 'high' },
    'password': { type: 'password', level: 'critical' },
    'pay_password': { type: 'password', level: 'critical' },

    /* 企业信息 */
    'company_name': { type: 'name', level: 'low' },
    'legal_person': { type: 'name', level: 'medium' },
    'credit_code': { type: 'code', level: 'high' },
};

/* 敏感级别 */
const SENSITIVE_LEVELS = {
    LOW: 1,      // 低敏感性,可显示部分
    MEDIUM: 2,   // 中敏感性,需要部分掩码
    HIGH: 3,      // 高敏感性,需要大部分掩码
    CRITICAL: 4, // 极高敏感性,完全隐藏
};

脱敏算法实现

针对不同类型数据的脱敏策略:

/* 数据脱敏服务 */
class DataMaskingService {
    /* 手机号脱敏:138****5678 */
    maskPhone(phone) {
        if (!phone) return '';
        return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
    }

    /* 身份证脱敏:320*******1234567 */
    maskIdCard(idCard) {
        if (!idCard) return '';
        return idCard.replace(/(\d{3})\d{10}(\d{4})/, '$1*******$2');
    }

    /* 银行卡脱敏:6222 **** **** 5678 */
    maskBankCard(card) {
        if (!card) return '';
        return card.replace(/(\d{4})\d{8}(\d{4})/, '$1 **** **** $2');
    }

    /* 姓名脱敏:张*三 */
    maskName(name) {
        if (!name) return '';
        const len = name.length;
        if (len === 1) return name;
        if (len === 2) return name[0] + '*';
        return name[0] + '*'.repeat(len - 2) + name[len - 1];
    }

    /* 邮箱脱敏:t***@example.com */
    maskEmail(email) {
        if (!email) return '';
        const [local, domain] = email.split('@');
        if (local.length <= 2) {
            return local[0] + '***@' + domain;
        }
        return local[0] + '***' + local[local.length - 1] + '@' + domain;
    }

    /* 密码完全隐藏 */
    maskPassword(password) {
        return '******';
    }

    /* 地址脱敏:保留省市 */
    maskAddress(address) {
        if (!address) return '';
        /* 只保留前 N 个字符或省市信息 */
        const parts = address.split(' ');
        if (parts.length >= 2) {
            return parts[0] + ' ' + parts[1] + '****';
        }
        return address.substring(0, 6) + '****';
    }
}

自动脱敏中间件

在 API 响应层面自动应用脱敏:

/* 响应脱敏中间件 */
class MaskingMiddleware {
    constructor(maskingService) {
        this.maskingService = maskingService;
    }

    process(data, fields, context) {
        if (!data || !fields) return data;

        /* 检查用户权限 */
        const userLevel = getUserSensitivityLevel(context.user);

        const result = {};
        for (const [key, value] of Object.entries(data)) {
            const config = SENSITIVE_FIELDS[key];

            if (!config) {
                result[key] = value;
                continue;
            }

            /* 检查是否需要脱敏 */
            if (config.level > userLevel) {
                result[key] = this.maskingService.mask(value, config.type);
            } else {
                result[key] = value;
            }
        }

        return result;
    }

    mask(value, type) {
        const method = 'mask' + type[0].toUpperCase() + type.slice(1);
        return this.maskingService[method]
            ? this.maskingService[method](value)
            : '***';
    }
}

脱敏策略原则

  • 一致性:同一字段在所有场景使用相同脱敏规则
  • 可逆性:必要时可还原(如管理员权限)
  • 可读性:保留足够信息便于识别
  • 性能:脱敏操作不应影响系统响应

字段级别脱敏配置

支持按业务模块配置脱敏策略:

/* 模块脱敏配置 */
const MODULE_MASKING_CONFIG = {
    'customer': {
        'name': { enabled: true, type: 'name' },
        'phone': { enabled: true, type: 'phone', roles: ['admin', 'sales'] },
        'id_card': { enabled: true, type: 'id_card', roles: ['admin'] },
    },
    'order': {
        'buyer_name': { enabled: true, type: 'name' },
        'buyer_phone': { enabled: true, type: 'phone' },
    },
    'finance': {
        'account': { enabled: true, type: 'account', roles: ['admin', 'finance'] },
        'bank_card': { enabled: true, type: 'bank_card', roles: ['admin', 'finance'] },
    }
};

/* 使用配置脱敏 */
function maskByModule(data, module, userRole) {
    const config = MODULE_MASKING_CONFIG[module];
    if (!config) return data;

    const result = { ...data };
    for (const [field, fieldConfig] of Object.entries(config)) {
        if (!fieldConfig.enabled) continue;

        /* 检查角色权限 */
        if (fieldConfig.roles && !fieldConfig.roles.includes(userRole)) {
            result[field] = maskValue(result[field], fieldConfig.type);
        }
    }

    return result;
}

日志脱敏

防止敏感信息写入日志:

/* 日志脱敏拦截器 */
class LogMaskingInterceptor {
    constructor() {
        this.fieldPatterns = [
            'password', 'passwd', 'pwd',
            'token', 'access_token',
            'phone', 'id_card',
            'bank_card', 'cvv'
        ];
    }

    mask(obj) {
        if (!isObject(obj)) return obj;

        const result = {};
        for (const [key, value] of Object.entries(obj)) {
            if (this.shouldMask(key)) {
                result[key] = '***MASKED***';
            } else if (isObject(value)) {
                result[key] = this.mask(value);
            } else {
                result[key] = value;
            }
        }
        return result;
    }

    shouldMask(key) {
        const lowerKey = key.toLowerCase();
        return this.fieldPatterns.some(p => lowerKey.includes(p));
    }
}

审计与合规

脱敏操作的完整审计追踪:

/* 脱敏审计日志 */
const MASKING_AUDIT_LOG = {
    table: 'audit_masking',
    fields: ['id', 'operator_id', 'operation',
             'module', 'field', 'action',
             'timestamp', 'ip']
};

/* 记录脱敏操作 */
async logMaskingOperation(operator, module, field, action) {
    await db.insert(MASKING_AUDIT_LOG.table, {
        operator_id: operator.id,
        operation: 'data_masking',
        module,
        field,
        action,
        timestamp: now(),
        ip: operator.ip
    });
}

总结

  • 字段分类:按敏感级别分类管理
  • 算法实现:针对不同类型定制脱敏规则
  • 中间件处理:API 响应自动脱敏
  • 角色权限:按角色控制脱敏程度
  • 日志安全:日志中不出现敏感信息
  • 审计追踪:记录所有脱敏操作