支付卡数据保护:PAN、CVV、PIN的存储与传输规则

聊到支付卡数据保护,我脑子里第一个蹦出来的就是PCI DSS标准。说白了,这套标准就是围绕三个核心数据要素展开的:主账号(PAN)、卡片验证码(CVV/CVC)、个人识别码(PIN)。这三样东西,在支付安全领域里被称为"皇冠上的明珠"——谁碰谁得小心。

我做过不少支付系统的渗透测试,发现很多团队对这三类数据的保护意识参差不齐。有人觉得CVV和PIN反正不存数据库就没事了,有人把PAN当普通字段处理。嗯,这里面的坑,我一个个说。

PAN:存储与传输的核心规则

PAN是支付卡数据保护的重中之重。PCI DSS要求,存储PAN时必须做不可逆的截断或加密。什么叫不可逆?就是你存了之后,没法从存储的数据里还原出完整的PAN。

我个人习惯的做法是:

  • 存储时:只保留前六位和后四位,中间用掩码替代。比如 411111******1111
  • 传输时:必须使用强加密通道,TLS 1.2以上是底线
  • 展示时:任何时候都不能显示完整PAN,除非有明确的业务必要

关键点:PCI DSS要求PAN在存储时必须加密或截断。但注意,截断后的数据如果还能通过算法还原,那就不算合规。我见过有公司用简单的XOR加密存PAN,结果被审计直接打回——这跟明文没区别。

CVV:存储的绝对禁区

CVV(卡片验证码)的规则简单到令人发指:交易完成后立即销毁,不得存储。这是PCI DSS的硬性要求,没有任何商量余地。

为什么这么严格?因为CVV是验证持卡人是否物理持有卡片的关键凭证。一旦被泄露,攻击者可以拿着它做无卡交易(CNP交易)。

我曾经审计过一个电商平台,发现他们把CVV存在了日志文件里。原因是开发人员为了方便调试,把整个请求体都打日志了。结果日志文件被运维人员误传到公开服务器上...嗯,那家公司后来被罚了六位数。

正确的做法是:

  • 交易请求中携带CVV,验证通过后立即丢弃
  • 任何系统组件(包括数据库、日志、缓存)都不允许存储CVV
  • 即使加密存储也不行——PCI DSS明确禁止

PIN:硬件安全模块的专属领地

PIN(个人识别码)的保护级别最高。它必须使用硬件安全模块(HSM)来处理,不能出现在应用服务器的内存里。

PIN的传输规则也很严格:

  • 必须使用HSM生成的密钥进行加密
  • 传输过程中必须使用双倍长密钥(Double-Length Key)
  • PIN块(PIN Block)的格式必须符合ISO 9564标准

你想想看,PIN是持卡人身份的最后一道防线。一旦PIN和卡片信息同时泄露,攻击者可以直接在ATM上取现。所以PCI DSS对PIN的保护要求是最高的。

加密与令牌化技术

说到数据保护技术,加密和令牌化是两个核心手段。很多人搞混这两者,我简单说说区别。

加密:可逆的保护

加密是把明文数据变成密文,需要密钥才能还原。在支付场景里,加密主要用于PAN的存储保护。

常用的加密方式:

  • AES-256:对称加密,适合数据库字段加密
  • RSA-2048:非对称加密,适合密钥交换
  • TDES:虽然还在用,但我建议尽快迁移到AES
// 示例:使用AES-256加密PAN
// 注意:实际生产环境需要使用HSM或密钥管理服务
public String encryptPAN(String pan, SecretKey key) {
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] iv = cipher.getIV();
    byte[] encrypted = cipher.doFinal(pan.getBytes());
    // 返回IV+密文的组合
    return Base64.getEncoder().encodeToString(iv) + ":" + 
           Base64.getEncoder().encodeToString(encrypted);
}

避坑指南:加密时一定要用认证加密模式(如GCM),不要只用CBC。我在项目中遇到过CBC模式被填充预言攻击的情况,那叫一个惨。另外,密钥轮换周期建议不超过一年。

令牌化:不可逆的替代

令牌化(Tokenization)是把敏感数据替换成一个无意义的令牌(Token)。令牌本身没有任何价值,即使泄露了也无法还原出原始数据。

令牌化的优势很明显:

  • 令牌不在PCI DSS的审计范围内
  • 可以降低合规成本
  • 适合需要频繁使用PAN的场景(如订阅支付)

我参与过一个大型电商的令牌化改造项目。他们把用户的PAN全部替换成令牌,数据库里只存令牌。支付时,令牌通过令牌服务(Token Service)映射回真实的PAN。这样一来,即使数据库被拖库,攻击者拿到的也只是一堆无意义的字符串。

数据留存与销毁策略

数据留存是个容易被忽视的点。很多公司只想着怎么保护数据,却忘了数据该留多久、怎么销毁。

留存期限:能短则短

PCI DSS要求,支付卡数据的留存期限必须基于业务必要性来确定。说白了,用完了就删,别留着占地方。

数据类型 建议留存期限 说明
PAN(加密存储) 交易完成后90天 用于对账和争议处理
CVV 0天 交易完成后立即销毁
PIN 0天 HSM处理完后不留存
交易日志 6个月-1年 根据当地法规调整

销毁策略:物理级清除

数据销毁不是简单的delete操作。在数据库里,delete只是标记删除,数据还在磁盘上。真正的销毁要做到物理级清除。

我推荐的做法:

  • 数据库层面:使用UPDATE覆盖原数据,再执行DELETE
  • 文件层面:使用shred或类似工具多次覆写
  • 硬件层面:磁盘消磁或物理粉碎

我曾经遇到过一个案例:某公司用DELETE删除了包含PAN的数据库记录,结果DBA从数据库的WAL日志里把数据全恢复出来了。所以记住,销毁要覆盖,覆盖要多次,多次要验证。

知识体系总览

下面这张图是我梳理的支付卡数据保护核心逻辑。你可以把它当作一个检查清单,看看自己的系统覆盖了哪些环节。

支付卡数据保护核心逻辑 PAN(主账号) CVV(验证码) PIN(个人识别码) 存储规则 加密或截断 前六后四掩码 存储规则 禁止存储 交易后立即销毁 存储规则 仅HSM处理 应用层不留存 保护技术 加密技术 AES-256 / RSA-2048 / GCM模式 令牌化技术 Token替代PAN / 降低合规成本 数据留存与销毁策略

这张图把整个支付卡数据保护的逻辑串起来了。从三个核心数据要素出发,到各自的存储规则,再到保护技术,最后落到留存与销毁策略。你可以在做系统设计时,对照这张图检查每个环节是否都覆盖到了。

最后说一句:支付卡数据保护不是一次性工作。PCI DSS每季度都要扫描,每年都要审计。我建议你把这些规则固化到开发流程里,而不是等到审计前才临时抱佛脚。


公众号:蓝海资料掘金营,微信deep3321