2. 支付 SDK 的持卡人数据识别:数据要素、存储位置、传输路径

2.1 合规要求拆解

PCI DSS 将持卡人数据严格区分为两类:持卡人数据要素(Cardholder Data, CHD)与敏感认证数据(Sensitive Authentication Data, SAD)。支付 SDK 在集成时必须从合规视角逐一识别、定位并管控这些数据,否则将面临高额罚款、断链甚至吊销支付牌照的风险。

PCI DSS 要求编号核心条款对支付 SDK 的约束
Req 3.2禁止存储敏感认证数据(SAD)SDK 不得在内存、日志、数据库、缓存中持久化或暂存 CVV2/PIN/磁条数据
Req 3.3屏蔽 PAN(展示时仅显示前六后四)SDK 界面、日志、调试输出中必须对 PAN 做截断或脱敏
Req 3.4存储的 PAN 必须加密或使用不可逆哈希SDK 若缓存 PAN(如重试队列),必须使用 AES-256 或更强算法
Req 4.2持卡人数据在公共网络传输必须使用强加密(TLS 1.2+)SDK 与收单机构间、SDK 与商户 App 间的通信链路必须满足 TLS 要求

合规证据要点:支付 SDK 需要提供一份《持卡人数据分类清单》,明确每个字段是否属于 CHD / SAD,并注明存储位置、保留期限、加密方式。该清单是 QSA(授权安全评估机构)现场审查的第一核对物。

2.2 持卡人数据要素识别

支付 SDK 在交易全生命周期中可能接触以下数据字段。必须按 PCI DSS 标准逐一标记,并建立数据要素台账。

数据字段CHDSADPCI DSS 存储限制SDK 中是否出现合规处置要求
主账号(PAN)✓✗存储须加密、展示须屏蔽是加密存储,日志脱敏
持卡人姓名✓✗允许存储是无特殊加密要求,但需控制访问权限
服务代码✓✗允许存储是与 PAN 一起加密
有效期✓✗允许存储是与 PAN 一起加密
CVV2 / CVC2✗✓禁止存储否(应屏蔽)SDK 必须确保不在任何位置持久化
PIN / 离线 PIN✗✓禁止存储否仅通过硬件加密键盘传递,SDK 不可获取明文
磁条数据(轨道 1/2/3)✗✓禁止存储否SDK 不得读取或缓存磁条原始数据
CAV2 / CVC2 令牌——允许存储(如符合 tokenization 标准)是须通过 PCI 认证的令牌系统生成

实操提醒:许多 SDK 在调试日志中无意记录了完整 PAN 或 CVV2,这直接违反 Req 3.2 和 Req 3.3。建议在 SDK 构建脚本中增加编译期注解或静态代码扫描规则,自动拦截 log 方法中出现的 pan / cvv 关键字。

支付 SDK 持卡人数据识别全景图 持卡人数据要素 • 主账号(PAN) • 持卡人姓名 • 有效期 | 服务代码 敏感认证数据(SAD) • CVV2 / CVC2 • PIN / 离线 PIN • 磁条数据(轨道 1/2/3) 存储位置识别 易失性内存 持久化数据库 日志文件 系统缓存 (每个位置须标记是否存在 CHD / SAD) 传输路径分析 商户 App → SDK 内部 SDK 内部 → 收单机构 调试 / 日志回传 (每条路径须确认加密协议与密钥强度) 合规管控红线:禁止存储 SAD | 加密存储 PAN | TLS 1.2+ | 审计检查与整改闭环

2.3 存储位置与风险识别

支付 SDK 在运行过程中会将持卡人数据暂存于不同介质。必须建立存储位置台账,逐一评估风险等级并实施管控。

存储位置持卡人数据风险PCI DSS 合规要求审计检查方法证据类型
应用堆内存 / 栈内存高使用后立即清零(Zeroize)内存快照分析、代码审查内存清零函数调用记录
日志文件(Logcat / 日志系统)极高禁止输出完整 PAN 及任何 SAD日志内容扫描工具日志脱敏策略配置 + 扫描报告
本地数据库(SQLite / SharedPreferences)中PAN 必须加密存储(AES-256)数据库文件加密验证加密字段 Schema + 加密算法证书
系统缓存(剪贴板 / 图片缓存)中禁止缓存 SAD;PAN 缓存须加密缓存目录遍历检查缓存策略设计文档
临时文件(TMP / 下载目录)高禁止明文写入;使用后立即删除文件系统监控临时文件清理脚本 + 审计日志

常见违规场景:开发阶段在 onSaveInstanceState() 中持久化 PAN;使用 Log.d() 打印卡号用于调试;将 PAN 作为图片水印写入缓存。这些行为在 QSA 审计中会被直接判定为 “不符合”,需立即整改。

2.4 传输路径分析

持卡人数据在支付 SDK 内部及外部通信中会经过多条传输路径。必须绘制数据流拓扑图,并对每条路径实施加密与访问控制。

传输路径通信方式传输的数据加密要求审计证据
商户 App → SDK 接口Binder / AIDL / JNIPAN、有效期、CVV2进程间通信须使用 TLS 或加密管道IPC 加密策略文档 + 代码审计
SDK 内部模块间函数调用 / 消息队列PAN、令牌内存中避免明文传递;使用安全缓冲区内部数据流设计文档
SDK → 收单机构网关HTTPS / RESTPAN、加密令牌TLS 1.2+,证书链验证SSL/TLS 配置截图 + 证书有效性报告
SDK → 日志 / 分析服务HTTPS脱敏后的统计信息不允许包含完整 CHD 或 SAD日志发送策略配置 + 数据采样样本

TLS 合规配置示例(证据材料):

{
  "transport_security": {
    "protocol": "TLSv1.2",
    "min_version": "1.2",
    "cipher_suites": [
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
    ],
    "certificate_pinning": true,
    "verify_hostname": true,
    "session_resumption": false
  },
  "logging": {
    "mask_pan": true,
    "mask_cvv": true,
    "output_level": "warn"
  }
}

证据链关键证据:上述 JSON 配置文件应纳入 SDK 的合规交付件,并由安全团队签字确认。同时配合网络抓包(Wireshark/tcpdump)确认实际传输链路使用了指定加密套件,抓包文件作为补充证据归档。

2.5 材料清单与台账

为支撑审计检查,支付 SDK 项目必须维护以下合规材料清单,并建立版本化的台账记录。

材料编号材料名称责任方更新频率保存期限
MAT-02-01持卡人数据分类清单安全工程团队每次数据接口变更≥审计周期
MAT-02-02存储位置台账运维 + 开发每月≥12 个月
MAT-02-03传输路径拓扑图架构师每季度≥2 个审计周期
MAT-02-04日志脱敏策略配置DevOps每次发布前随版本存档
MAT-02-05加密算法与密钥管理方案安全工程团队年度 / 加密算法变更≥5 年
MAT-02-06静态代码扫描报告(数据泄露专项)QA每次 CI 构建≥6 个月

2.6 证据链与审计检查

QSA 在审查支付 SDK 时,会围绕“识别 → 定位 → 管控 → 验证”四阶段索取证据。以下是最常见的审计检查点及对应的证据链设计。

审计阶段检查点QSA 提问示例必需证据
识别数据分类是否完整“请出示 SDK 涉及的所有持卡人数据字段清单”MAT-02-01 签字版
存储所有存储位置是否已标记“PAN 在 SDK 中存储在哪些位置?如何加密?”MAT-02-02 + 加密方案文档
传输传输路径是否全覆盖“SDK 与收单机构之间使用什么协议?”MAT-02-03 + TLS 配置截图
日志日志是否包含 CHD/SAD“请提供最近一周的日志样本用于审查”日志脱敏策略 + 扫描工具报告
清零内存使用后是否清零“请展示 PAN 使用完毕后内存清零的代码路径”代码审查记录 + 单元测试

构建证据链的技巧:每个审计检查点对应一个独立证据文件夹,命名规则为 EVIDENCE-02-<检查点编号>-<版本号>。例如 EVIDENCE-02-01-v2.3 存放第 2 章“持卡人数据分类清单”第 2.3 版的签字扫描件。文件夹内同时放入 README.md 说明证据生成时间、工具、责任人。

2.7 整改闭环

针对审计或自检中发现的数据识别、存储、传输问题,必须建立整改闭环跟踪表,确保每项风险可追踪、可验证、可复现。

风险编号风险描述发现来源整改措施验证方法负责人闭环日期闭环证据
RISK-02-01日志输出完整 PAN代码扫描增加日志脱敏过滤器,替换 Log.d() 为安全日志类扫描工具复检通过张三2025-02-10扫描报告 + MR 记录
RISK-02-02CVV2 暂存在 SharedPreferences设计评审移除 SAD 存储逻辑,改用内存临时变量并在使用后清零代码审查 + 内存分析李四2025-02-14代码 diff + 清零函数测试用例
RISK-02-03TLS 配置未启用证书固定安全测试在 SDK 初始化配置中添加 certificate_pinning 证书哈希中间人攻击测试王五2025-02-18配置变更记录 + 渗透测试报告

日志脱敏整改代码示例(证据材料):

// SafeLogger.java —— 支付 SDK 安全日志工具
public class SafeLogger {
    private static final String TAG = "PaymentSDK";

    public static void d(String message) {
        // 自动屏蔽 PAN 和 CVV2 模式
        String safe = message
            .replaceAll("\\b(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})\\b", "****PAN_MASKED****")
            .replaceAll("\\b[0-9]{3,4}\\b(?=.*(?:cvv|cvc))", "***");
        Log.d(TAG, safe);
    }

    public static void writeAuditLog(String event, String maskedPan) {
        // 只记录脱敏后的 PAN(前六后四)
        if (maskedPan != null && maskedPan.length() >= 10) {
            String safePan = maskedPan.substring(0, 6) + "****" + maskedPan.substring(maskedPan.length() - 4);
            Log.i(TAG, "audit:" + event + "|pan=" + safePan);
        }
    }
}

整改验证硬规则:所有整改措施必须经过“三重验证”——① 自动化测试通过;② 安全团队 Code Review 通过;③ QSA 或内部审计员抽样确认。缺少任意一环,该风险项不得标记为“已闭环”。