对持卡人敏感数据进行标记化处理以满足 PCI DSS 要求

Last reviewed 2023-05-05 UTC

本教程介绍如何在 Cloud Functions 上设置受访问权限控制的信用卡和借记卡标记化服务。为设置该服务,本文使用以下 Google Cloud 服务:Identity and Access Management (IAM)Cloud Key Management Service (KMS)

标记化是将信用卡数据等敏感信息替换为良性占位符(或称标记)的过程。支付卡行业数据安全标准 (PCI DSS) 的第 3 部分要求将信用卡上存储的大部分数据视作敏感信息。

令牌本身没有意义,它只是作为一种用于在特定上下文中查找经过标记化的数据的方法。但是,您仍然需要确保您的标记不包含任何特定于用户的信息,并且不能直接解密。这样一来,即使您失去对客户支付卡标记的控制,任何人也无法使用标记来窃取持卡人数据。

用于处理敏感信息的服务

可供您选择的用于托管持卡人数据环境 (CDE) 的平台或服务多种多样。本教程将指导您使用 Cloud Functions 进行示例部署,并帮助您完成后续步骤,获得可直接用于生产环境的解决方案。

Cloud Functions 是用于托管和执行代码的无服务器平台,借助它,您可以方便地快速启动无需干预即可扩缩的应用。请注意,在兼容 PCI DSS 的 CDE 中,您必须将所有入站和出站流量限制为已获授权的连接。Cloud Functions 目前不支持此类精细控制。因此,您必须在其他位置(例如在应用中)实现补偿性控制,或者选择其他平台。相同的标记化服务可采用容器化方式运行,例如自动扩缩的托管实例组或 Kubernetes 集群。它们是具有完整 VPC 网络控制的首选生产环境。

Cloud KMS 是 Google Cloud 的密钥管理服务。Cloud KMS 托管您的加密密钥、定期轮替加密密钥,并对存储的账号数据进行加密或解密。

本教程使用 IAM 来严格控制标记化服务中使用的所有资源。您需要一个标记经常过期的特殊服务账号,以便授予对 Cloud KMS 的访问权限以及执行标记生成器。

下图展示了您在本教程中创建的标记化应用架构。

标记化应用架构

目标

  • 创建服务账号。
  • 设置 Cloud KMS。
  • 创建两个 Cloud Functions 函数。
  • 创建身份验证标记。
  • 调用标记生成器。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

准备工作

  1. 在 Google Cloud Console 中,转到项目选择器页面。

    转到“项目选择器”

  2. 要开始创建 Google Cloud 项目,请点击创建项目

  3. 为您的项目命名。记下生成的项目 ID。

  4. 根据需要修改其他字段。

  5. 如需创建项目,请点击创建

  6. 确保您的 Google Cloud 项目已启用结算功能

  7. 启用 Cloud Build, Cloud Functions, and Cloud KMS API。

    启用 API

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

创建服务账号

Cloud Functions 的默认运行时服务账号具有 Editor 角色,该角色允许广泛访问许多 Google Cloud 服务。虽然这是开发函数的最快方法,但 Google 仍建议您仅使用默认服务账号进行测试和开发。您可以创建一个服务账号,以根据最小权限原则限制函数可以使用的 API。如需创建服务账号,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到服务账号页面。

    转到“服务账号”

  2. 选择您的项目。

  3. 点击创建服务账号

  4. 服务账号名称字段中,输入 Tokenization Service User。Google Cloud 控制台会根据此名称填充服务账号 ID 字段。

  5. 可选:在服务账号说明字段中,输入服务账号的说明。

  6. 点击创建并继续

  7. 点击选择角色,然后选择 Cloud KMS CryptoKey Encrypter/Decrypter

  8. 如需完成服务账号的创建过程,请点击完成

    现在,您已经拥有一个具有以下电子邮件地址的服务账号用户:

    tokenization-service-user@YOUR_PROJECT_ID.iam.gserviceaccount.com

设置 Cloud KMS

  1. 在 Google Cloud 控制台中,打开密钥管理

    转到“加密密钥”页面

  2. 点击 **+ 创建密钥环 **。在显示的对话框中,执行以下操作:

    1. 将该密钥环命名为 tokenization-service-kr
    2. 对于密钥环位置,选择全局。通常此选项就足以满足本教程的要求。但在做出任何生产架构决策之前,请确保您了解各个 Cloud KMS 位置之间的差异
    3. 请仔细检查您的所选项,因为创建密钥环之后,您无法对其执行删除或重命名操作
    4. 点击创建

      创建密钥环

    系统会创建密钥环并将您转到“密钥创建”页面。

  3. 创建密钥对话框中,执行以下操作:

    1. 将该密钥命名为 cc-tokenization
    2. 对于用途,请选择 Symmetric encrypt/decrypt
    3. 轮替周期设置为您选择的值,然后点击创建

    跟踪密钥的相关信息

创建 Cloud Functions 函数

本教程假设您将使用 Cloud Shell。如果您使用其他终端,请确保使用最新版本的 Google Cloud CLI

  1. 在 Google Cloud 控制台中,打开 Cloud Shell:

    转到 Cloud Shell

  2. 克隆 GitHub 项目代码库并移动到工作文件夹:

    git clone https://github.com/GoogleCloudPlatform/community gcp-community
    cd gcp-community/tutorials/pci-tokenizer/
    

    gcs-cf-tokenizer 文件夹包含 index.js 文件,该文件是您要创建的两个不同 Cloud Functions 函数的来源。它还包含 package.json,用于告知 Cloud Functions 函数要运行哪些软件包。

  3. 应用 KMS 配置 复制配置模板文件并打开以进行修改:

    cp config/default.json config/local.json
    nano config/local.json
    

    Node.js 运行时要求您显式定义 Google Cloud 项目 ID:

    "project_id":              "YOUR_PROJECT_ID"
  4. 找到 KMS 配置并应用您在上一部分中创建的 KMS 值:

    "location":                "global",
    "key_ring":                "tokenization-service-kr",
    "key_name":                "cc-tokenization"
    
  5. 部署标记化函数。

    gcloud functions deploy tokenize --runtime=nodejs18 --trigger-http \
        --entry-point=kms_crypto_tokenize --memory=256MB \
        --service-account=tokenization-service-user@YOUR_PROJECT_ID.iam.gserviceaccount.com \
        --no-allow-unauthenticated --source=.
    

    此函数会将信用卡信息转换为标记。

  6. gcloud functions deploy 命令的输出中的 httpsTrigger 下查找网址值。将网址的值存储在 TOK_URL 环境变量中:

    TOK_URL="TOK_URL"

    您将使用 TOK_URL 环境变量调用 tokenize 函数。

  7. 在 KMS 模式下部署去标记化函数。

    gcloud functions deploy detokenize --runtime=nodejs18 --trigger-http \
        --entry-point=kms_crypto_detokenize --memory=256MB \
        --service-account=tokenization-service-user@YOUR_PROJECT_ID.iam.gserviceaccount.com \
        --no-allow-unauthenticated --source=.
    

    此函数逆转标记化过程。

  8. gcloud functions deploy 命令的输出中的 httpsTrigger 下查找网址值。将网址的值存储在 DETOK_URL 环境变量中:

    DETOK_URL="DETOK_URL"

    您将使用 DETOK_URL 环境变量调用去标记化函数。

    您创建了两个单独的 Cloud Functions 函数:一个用于将卡号转换为标记,另一个用于逆转此过程。不同的入口点将执行定向到 index.js 文件中的正确启动函数。

  9. 部署好函数后,打开 Cloud Functions 控制台。

    打开 Cloud Functions 控制台

  10. 验证函数已创建。如果一切顺利,您会看到两个函数,每个函数旁边都有一个对勾标记。

    验证已创建 Cloud Functions 函数

创建身份验证标记

gcloud functions deploy 命令中的 no-allow-unauthenticated 选项表示调用函数的调用者必须提供身份验证标记来声明调用者的身份。调用者必须具有 cloudfunctions.functions.invoke 权限。以下预定义角色具有此权限:Cloud Functions Invoker、Cloud Functions Admin 和 Cloud Functions Developer。

  • 创建身份验证标记:

    AUTH_TOKEN=$(gcloud auth print-identity-token)
    echo $AUTH_TOKEN
    

这些命令会生成身份验证标记字符串,将其存储在环境变量 $AUTH_TOKEN 中,然后显示标记。稍后您调用使用该标记部署的 Cloud Functions。

调用标记生成器

  1. 创建一些示例数据,将它们传递给标记生成器:

    export TOK_CC=4000300020001000
    export TOK_MM=11
    export TOK_YYYY=2028
    export TOK_UID=543210
    
  2. 按照上一节中描述的步骤生成身份验证标记,然后调用标记生成器:

    CC_TOKEN=$(curl -s \
    -X POST "$TOK_URL" \
    -H "Content-Type:application/json" \
    -H "Authorization: Bearer $AUTH_TOKEN" \
    --data '{"cc": "'$TOK_CC'", "mm": "'$TOK_MM'", "yyyy": "'$TOK_YYYY'", "user_id": "'$TOK_UID'"}' \
    )
    echo $CC_TOKEN
    

    此时会显示表示信用卡数据的标记化字符串。此字符串已存储在环境变量 CC_TOK 中。您可以通过调用标记取消器检索卡片信息。

  3. 使用以下命令逆转标记化。

    DETOK_DATA=$(curl -s \
    -X POST "$DETOK_URL" \
    -H  "Content-Type:application/json" \
    -H "Authorization: Bearer $AUTH_TOKEN" \
    --data '{"user_id": "'$TOK_UID'", "token": "'$CC_TOKEN'"}' \
    )
    echo -e "$DETOK_DATA\n"
    

    输出结果类似于以下内容:

    {"cc":"4000300020001000","mm":"11","yyyy":"2028","userid":"543210"}
    

    此数据是最初发送到标记生成器的数据,由您的应用解密和检索。

在本教程中展开

GitHub 上的示例代码是个不错的起点,但在进入生产阶段之前还有许多需要考虑的问题。

如果您选择使用 Cloud Functions 对支付卡进行标记化处理,则可能需要完成更多工作才能满足合格安全评估机构或自我评估调查问卷的要求。具体而言,PCI DSS 第 1.2 和 1.3 节要求严格控制入站和出站流量。由于 Cloud Functions 和 App Engine 并未提供双向的可配置的防火墙,因此您必须创建补偿性控制,或者在 Compute Engine 或 Google Kubernetes Engine 上部署标记化服务。如果您想探索容器化,GitHub 代码与 Docker 兼容,并包含支持文档。

此示例代码还引入了部署的 npm(Node.js 包管理器)依赖项。在生产环境中,请始终将依赖项固定到特定的经过审核的版本。然后将这些版本与应用捆绑到一起,您也可以从受信任的非公开位置提供这些版本。这两种方法都可以使您免遭因公共 npm 代码库中断或者对您认为安全的包造成影响的供应链攻击而导致的停机。如果您预先构建并捆绑完整的应用,则部署时间通常会缩短,这意味着启动速度更快,扩缩更顺畅。

清理

如需清理本教程中使用的各个资源,您可以删除该项目。

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤