菜单

PCI DSS 测试数据:测试环境也在合规范围内

PCI DSS 对测试数据的要求常被误读成只管生产环境。本文说明为什么真实卡号不能进测试库、敏感认证数据为什么不得保存,以及掩码、令牌化与合成数据各自解决什么问题。

发布于

  • 合规
  • 测试数据

一个很常见的场景:为了重现线上问题,有人从生产数据库导出了一份样本,脱敏后灌进测试环境。看起来谨慎,实际上已经踩线了。这项支付行业的安全标准对测试环境有明确要求,而它约束的正是这类看起来无害的操作。本文想讲清楚的是:为什么测试环境会被纳入合规范围,以及在实际工程里该用哪些手段替代真实数据。

这不是一份合规条文的解读,而是一份工程视角的说明。具体条款请以标准的最新版本与你的合规评估为准。

测试环境为什么也在范围内?

误解通常来自一个隐含假设:只要不碰真实用户,就不算处理持卡人数据。但标准关注的是数据本身,而不是环境的名字。

只要一套系统的数据库、日志或备份里出现过真实的卡号或安全码,那套系统就进入了适用范围。测试环境往往恰恰是最容易满足这个条件的地方:它通常共享生产的部分配置,权限管得更松,备份保留得更随意,而工程师在里面做的事又最多——导数据、改数据、复现问题。

把测试环境排除在外,等于给整条链路留了一个没人看着的入口。所以标准要求:开发与测试环境不得使用真实的持卡人数据,应当改用合成数据或由支付服务商提供的引用。

这也解释了一个常被低估的成本项:合规范围是由系统边界决定的,而边界往往比你想的大。测试环境、持续集成里跑数据的机器、开发本地的数据库快照、导出的对账文件,只要它们碰到过真实卡号,就在范围内。缩小范围的唯一办法不是声明,而是让真实数据压根不进入这些地方。

哪两类数据被区别对待?

标准把相关数据分成两类,处理方式完全不同。理解这个区分,比记住任何条款都管用:

类别 包含什么 允许的处理方式
存储的账户数据 卡号、有效期、持卡人姓名 可以保存,但必须受保护
敏感认证数据 安全码、完整磁道数据、个人识别码 授权完成后禁止保存,哪怕是加密形式

第二类是硬线。它不是「保存时要加密」,而是「不许保存」。原因在于这类数据的唯一用途是证明卡在持卡人手上或证明这是真实卡片;一旦它和卡号一起长期留存,这两道证明就同时失效了。安全码的规则细节见CVV 是什么。

第一类则允许保存,代价是要按标准做保护:存储时要加密或做等效处理,展示时必须掩码。掩码的含义是只显示号码的首段与末段,中间用固定字符代替,让人能认出是哪张卡却无法还原完整号码。

掩码、令牌化、合成数据各解决什么

三种手段经常被混为一谈,其实各自解决的层次不同:

  • 掩码解决的是「看得见」的问题。它让界面和报表上的号码不再完整,但底层存储的仍然是原值,因此它只是一种展示层手段,不减少需要保护的数据量。
  • 令牌化解决的是「存什么」的问题。系统里不再保存卡号本身,而是保存支付服务商签发的一个引用,真正发起扣款时用这个引用去换取授权。即使数据库泄露,泄露的也只是一串无意义的标识。
  • 合成数据解决的是「测什么」的问题。它完全替换掉真实数据,用格式正确、行为可预期的号码来支撑开发与测试,从源头上避免真实持卡人数据流入测试链路。

掩码本身也有一个容易被忽略的细节:保留哪几位并不完全统一。常见的做法是保留前六位与后四位,前面那段用于路由与对账,后面那段用于人工核对。无论采用哪种格式,它都必须稳定——同一张卡在日志、客服后台和用户账单里应当是同一个样子,否则排查问题时没人能确认自己看的是不是同一条记录。掩码格式一旦对外可见,它就成了一份对外契约,所以不要让它可选,可选就意味着每个系统都会自己发明一种。

在本站生成的号码属于哪一类

用信用卡号生成器生成的号码属于第三类:合成数据。它们按公开的编号方案拼出,长度、前缀与校验位都符合规则,因此能顺利通过任何读取格式的程序;但它们不对应任何账户,其中的姓名与有效期也都是示例值。

这正好满足上面那条要求——测试环境不使用真实的持卡人数据。生成一批多样化的号码灌进本地数据库,比想办法「脱敏」一份生产导出要简单得多,也不用承担额外的合规负担。要说清一点:这些号码结构上合法,但从未发行给任何人,也不对应任何真实账户,因此它们只能用于联调与测试,绝不能拿去对真实支付网关发起请求。需要按卡组织构造测试集时,可以参考各卡组织的测试号段。

需要说明的一点是:合成数据能替代真实数据的部分仅限于格式与流程。涉及真实风控、真实额度、真实拒绝原因的场景,仍然只能在受控的真实环境中验证,不能靠合成数据蒙混过去。

给开发者:把规则写进流程里

合规要求如果不落到具体动作上,就会在赶进度时被绕过。下面这些做法能把它固定下来:

  • 环境隔离:开发与测试环境不得连生产数据库,包括只读连接。只读连接同样会把真实卡号带进测试环境。
  • 不导真实数据:需要样本时用合成数据生成,而不是导出再脱敏。脱敏过程中的中间文件是常见的泄露源。
  • 日志字段过滤:在日志层面对卡号、安全码、个人识别码做固定替换,并且确认错误上报工具也做了同样的处理。异常堆栈里常常带着完整请求参数。
  • 字段级最小化:新建表时先问一句这个字段真的需要吗。不需要的字段不存在,就不会出问题。
  • 测试数据版本化:把合成数据做成受版本控制的文件,任何人拉下代码就能得到同一份数据。这样就不会有人为了排查问题临时从生产捞一份。细节见测试信用卡号是什么。
  • 上线前检查显示:确认界面、导出文件、客服后台、对账单里的号码都做了掩码,而不只是前台页面做了。

最后一条常被漏掉:令牌化和掩码上线之后,真正需要检查的是「哪里还能看到完整号码」。把完整号码的可见路径列出来,逐条确认是否必要,比逐条对照条款更有效率。

下一步

记住两层结论。第一层是判断:只要系统里出现过真实持卡人数据,它就进入适用范围,环境名字不能豁免。第二层是手段:能替换就替换,必须保留就保护,必须展示就掩码。

要开始替换测试数据,用信用卡号生成器生成一批合成号码;需要区分服务商测试卡与合成号码的用途差异,读Stripe 测试卡怎么用;上线前的整体自查项目见支付表单测试清单。

继续阅读

信用卡号生成器(测试用)相关文章