问题修复
处理支付卡数据时实施 PCI DSS 合规与卡数据安全
在构建支付处理系统、处理信用卡信息、实现安全支付流程、准备 PCI DSS 评估或缩小 PCI 合规范围时,用来安全处理持卡人数据并满足 PCI DSS 要求。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
处理支付卡数据时实施 PCI DSS 合通用
解决思路
- 安装并维护防火墙配置,保护支付网络。
- 不要使用供应商提供的默认密码。
- 保护存储的持卡人数据。
- 对通过公共网络传输的持卡人数据加密。
- 保护系统免受恶意软件侵害。
- 开发和维护安全的系统与应用。
- 按业务需要知悉原则限制对持卡人数据的访问。
- 识别并认证对系统组件的访问。
- 限制对持卡人数据的物理访问。
- 跟踪并监控对网络资源和持卡人数据的所有访问。
- 定期测试安全系统和流程。
- 维护覆盖信息安全的政策。
- 根据年交易量确定 PCI 合规级别:Level 1 为 > 6 million transactions/year,需年度 ROC。
- Level 2 为 1-6 million transactions/year,需年度 SAQ。
- Level 3 为 20,000-1 million e-commerce transactions/year。
- Level 4 为 < 20,000 e-commerce 或 < 1 million total transactions。
- 数据最小化:绝不存储 full track data(磁条数据)。
- 绝不存储 CVV(卡验证码/值)。
- 绝不存储 PIN 或 PIN block。
- 仅在加密后存储允许的数据:PAN、持卡人姓名、有效期、service code。
- 在 PaymentData 中定义禁止字段列表:['cvv', 'cvv2', 'cvc', 'pin']。
- 实现 sanitize_log(data):复制数据,若存在 card_number 则掩码为前 6 位 + '*' * (len(card) - 10) + 后 4 位,并删除禁止字段。
- 实现 validate_no_prohibited_storage(data):遍历禁止字段,若存在则抛出 SecurityError。
- 使用支付处理商 token 化:创建支付方式 token 只能在客户端用 Stripe.js 完成,绝不把卡详情发送到服务器。
- 客户端用 stripe.createToken({card: {number: '4242424242424242', exp_month: 12, exp_year: 2024, cvc: '123'}}) 获取 token,并把 token.id 发送到服务器。
- 服务器用 token 收费:设置 stripe.api_key,调用 stripe.Charge.create(amount, currency, source=token_id, description),服务器只看到 token。
- 存储支付方式:调用 stripe.Customer.modify(customer_id, source=payment_method_token),数据库只存 customer_id 和 payment_method_id,绝不存实际卡详情。
- 自定义 token 化(若必须存储卡数据):实现 TokenVault,使用 Fernet(encryption_key) 加密,生产环境使用加密数据库而不是内存 dict。
- TokenVault.tokenize(card_data):用 secrets.token_urlsafe(32) 生成安全随机 token,JSON 序列化并用 Fernet 加密 card_data,保存 token -> encrypted data 映射,返回 token。
- TokenVault.detokenize(token):从 vault 获取加密数据,不存在则抛 ValueError('Token not found'),用 Fernet 解密并 JSON 反序列化返回。
- TokenVault.delete_token(token):从 vault 中删除 token。
- 静态数据加密:实现 EncryptedStorage,使用 AES-256-GCM,key 必须为 32 bytes。
- EncryptedStorage.encrypt(plaintext):用 os.urandom(12) 生成随机 nonce,用 AESGCM(self.key).encrypt(nonce, plaintext.encode(), None) 加密,返回 nonce + ciphertext。
- EncryptedStorage.decrypt(encrypted_data):取前 12 字节为 nonce,剩余为 ciphertext,用 AESGCM(self.key).decrypt(nonce, ciphertext, None) 解密并解码返回。
- 使用 EncryptedStorage:storage = EncryptedStorage(os.urandom(32)),encrypted_pan = storage.encrypt('4242424242424242'),将 encrypted_pan 存入数据库。
- 传输数据加密:始终使用 TLS 1.2 或更高版本。
- Flask/Django 安全 Cookie 配置:SESSION_COOKIE_SECURE=True,SESSION_COOKIE_HTTPONLY=True,SESSION_COOKIE_SAMESITE='Strict'。
- 强制 HTTPS:使用 from flask_talisman import Talisman,Talisman(app, force_https=True)。
- 阅读 references/details.md 获取更详细的模板、完整模式库和工作示例。
适用边界 · 注意事项
- 如果系统完全不接触、不处理、不存储、不传输持卡人数据,则不需要实施 PCI DSS 卡数据控制,只需确认合规范围。
- 如果已将全部支付卡处理外包给合规支付页面或托管字段,且自身系统不接触卡数据,应优先依赖第三方合规证明并确认 SAQ 范围,而不是自行实现完整卡数据存储与加密体系。
- 本技能不能替代正式 PCI DSS 评估、ROC/SAQ 或法律合规意见。