配置消息加密

默认情况下,Pub/Sub 会静态加密客户内容。Pub/Sub 会为您处理加密,您无需执行任何其他操作。此选项称为“Google 默认加密”。

如果您想要控制加密密钥,则可以将 Cloud KMS 中客户管理的加密密钥 (CMEK) 与集成 CMEK 的服务(包括 Pub/Sub)搭配使用。使用 Cloud KMS 密钥时,您可以控制其保护级别、位置、轮替时间表、使用和访问权限以及加密边界。 使用 Cloud KMS 还可让您跟踪密钥使用情况、查看审核日志以及控制密钥生命周期。 这样您就可以在 Cloud KMS 中控制和管理用于保护数据的对称密钥加密密钥 (KEK),而不是由 Google 拥有和管理这些密钥。

使用 CMEK 设置资源后,访问 Pub/Sub 资源的体验与使用 Google 默认加密功能类似。如需详细了解加密选项,请参阅客户管理的加密密钥 (CMEK)。

将 CMEK 与 Cloud KMS Autokey 结合使用

您可以手动创建 CMEK 来保护 Pub/Sub 资源,也可以使用 Cloud KMS Autokey。借助 Autokey,系统会按需生成密钥环和密钥,以支持在 Pub/Sub 中创建资源。系统会创建使用密钥执行加密和解密操作的服务代理(如果它们尚不存在),并向其授予所需的 Identity and Access Management (IAM) 角色。如需了解详情,请参阅 Autokey 概览。

CMEK 如何与 Pub/Sub 搭配使用

当您为 Pub/Sub 配置 CMEK 时,该服务会自动使用指定的密钥对所有数据进行加密。CMEK 的 Cloud KMS 使用量可能会产生额外费用,具体取决于您的使用模式。

每条消息都会在以下状态和层级进行加密:

在应用层,Pub/Sub 会在收到消息后立即对每条消息进行单独加密。此实现增加了以下功能:

信封加密模式

Pub/Sub 通过 CMEK 使用信封加密模式。在此方法中,Cloud KMS 不会对消息进行加密。相反,Cloud KMS 用于加密 Pub/Sub 为每个主题创建的数据加密密钥 (DEK)。这些 DEK 仅由 Pub/Sub 以加密(封装)形式存储。存储 DEK 之前,服务会将 DEK 发送到 Cloud KMS,以便使用在主题上指定的 KEK(密钥加密密钥)对 DEK 进行加密。系统大约每六个小时就会为每个主题生成一个新的 DEK。

Pub/Sub 向订阅发布消息之前,会使用系统为相应主题生成的最新 DEK 对消息进行加密。Pub/Sub 会在消息传送给订阅者之前不久对其进行解密。

Cloud KMS 密钥区域

由于 Pub/Sub 资源是全局性的,因此我们建议您使用全局 Cloud KMS 密钥来配置启用 CMEK 的主题。使用区域性 Cloud KMS 密钥可能会对跨区域网络链接造成不必要的依赖,具体取决于主题的发布者和订阅者的位置。

仅在以下情况下使用区域级 Cloud KMS 密钥:

在这些情况下,主题的所有流量都会路由到同一区域。

将 CMEK 与 Pub/Sub 搭配使用

您可以手动配置 CMEK,也可以使用 Autokey 进行配置。

准备工作

您可以使用 Google Cloud 控制台或 Google Cloud CLI 为 Pub/Sub 配置 CMEK。

完成以下任务:

  • 启用 Cloud KMS API。

  • 在 Cloud KMS 中创建密钥环和密钥。无法删除密钥和密钥环。

如需了解如何完成这些任务,请参阅创建密钥环和创建密钥。

所需的角色和权限

Pub/Sub 使用 Google Cloud 服务代理来访问 Cloud KMS。服务代理在内部由 Pub/Sub 为每个项目维护,默认情况下不会显示在 Google Cloud 控制台的服务账号页面上。

Pub/Sub 服务代理采用 service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com 格式。

Pub/Sub 需要特定权限才能使用 CMEK 加密和解密数据。

完成以下步骤以设置所需的访问权限:

  • 向 Pub/Sub 服务代理授予 Cloud KMS Crypto Key Encrypter/Decrypter (roles/cloudkms.cryptoKeyEncrypterDecrypter) 角色。

    gcloud kms keys add-iam-policy-binding CLOUD_KMS_KEY_NAME \
        --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
        --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
    

    替换以下内容:

    • CLOUD_KMS_KEY_NAME:Cloud KMS 密钥的名称。

      密钥的格式为 projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/CRYPTO_KEY。

      例如 projects/test-project/locations/us-central1/keyRings/test-keyring/cryptoKeys/test-key。

    • PROJECT_NUMBER:Pub/Sub 项目的项目编号。

如需详细了解如何授予 Identity and Access Management 角色,请参阅授予对资源的角色。

使用 CMEK 手动配置主题

您可以使用 Google Cloud 控制台或 gcloud CLI 为主题手动配置 CMEK。

控制台

如需创建启用 CMEK 的主题,请按以下步骤操作:

  1. 在 Google Cloud 控制台中,前往 Pub/Sub 主题页面。

    转到“主题”

  2. 点击创建主题。

  3. 在主题 ID 字段中,输入主题 ID。

    如需详细了解主题命名,请参阅命名准则。

  4. 在加密部分,点击 Cloud KMS 密钥。

  5. 选择密钥类型。如果您没有看到选择客户管理的密钥下拉菜单,请确保您已为项目启用 Cloud KMS API。

  6. 点击创建主题。

gcloud

  1. 在 Google Cloud 控制台中,激活 Cloud Shell。

    激活 Cloud Shell

    Cloud Shell 会话随即会在 Google Cloud 控制台的底部启动,并显示命令行提示符。Cloud Shell 是一个已安装 Google Cloud CLI 且已为当前项目设置值的 Shell 环境。该会话可能需要几秒钟时间来完成初始化。

  2. 如需创建具有 CMEK 的主题,请运行 gcloud pubsub topics create 命令:

        gcloud pubsub topics create TOPIC_ID --topic-encryption-key=ENCRYPTION_KEY
        

    替换以下内容:

    • TOPIC_ID:主题的 ID 或名称。

      如需详细了解如何命名主题,请参阅 主题、订阅、架构或快照命名指南。

    • ENCRYPTION_KEY:要用于主题的 CMEK 的 ID。

      格式为 projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/CRYPTO_KEY。

手动更新 CMEK 主题

您可以灵活地添加、更改或移除与 Pub/Sub 主题关联的 CMEK。您可以使用 gcloud CLI 更新 CMEK。不过,此变更不会溯及既往。

在密钥更改之前发布到主题的消息仍使用原始密钥进行加密,无论该密钥是 CMEK 还是Google-owned and Google-managed encryption key。更改主题的 CMEK 不会重新加密之前发布的消息,这些消息仍受其最初加密时所用密钥的保护,因此主题中的消息数据可能仍依赖于之前的密钥,最长可达 31 天,具体取决于主题或其任何订阅中指定的消息保留时长。

Pub/Sub 具有密钥缓存机制,缓存时间约为 30 分钟。Pub/Sub 最多可能需要这么长时间才能识别并开始使用在主题配置中手动更改的新密钥。

Pub/Sub 中的 Cloud KMS 密钥轮替

Cloud KMS 中的密钥配置更改(例如密钥轮替)不会直接触发在 Pub/Sub 中创建数据加密密钥。Pub/Sub 最多可能需要 12 小时才能开始使用新密钥版本来加密消息数据。

与对 Pub/Sub 中的加密设置进行的手动配置更改一样,这些更改不会追溯应用于过去发布的消息。现有消息会继续受先前版本的加密密钥保护。这些消息仍受其最初加密时所用密钥的保护,因此主题中的消息数据可能仍依赖于之前的密钥版本,最长可达 31 天,具体取决于主题或其任何订阅中指定的消息保留时长。

使用 Cloud KMS Autokey 配置主题

如需详细了解如何将 Cloud KMS Autokey 与 Pub/Sub 搭配使用,请参阅 Cloud KMS with Autokey。

审核日志

启用密钥、停用密钥或 Pub/Sub 使用密钥对消息进行加密和解密时,Cloud KMS 会生成审核日志。这在排查发布或传送问题时很有用。

Cloud KMS 密钥会附加到 Pub/Sub 主题资源的审核日志中。Pub/Sub 不包含与 Cloud KMS 相关的任何其他信息。

价格和费用

对于以下 Pub/Sub 请求,使用 CMEK 会产生基于 Pub/Sub 价格的 Cloud KMS 服务使用费:

  • 对于使用 CMEK 的每个主题,系统每六个小时会对新的 DEK 进行加密和存储。

  • 系统每六分钟会使用该密钥对 DEK 进行解密。解密操作会执行三次(运行 Pub/Sub 服务的区域中的每个地区执行一次)。

例如,假设有一个主题,该主题具备以下条件:

  • 至少有一个订阅

  • 发布者和订阅者客户端位于同一区域

Cloud KMS 加密操作的次数可以按以下公式估算:

1 key access for ENCRYPT * (30 days / month * 24 hours / day) / 6 hours
 + 3 key accesses for DECRYPT
   * (30 days / month * 24 hours / day * 60 minutes / hour ) / 6 minutes
   = 21,720 Cloud KMS key access events
假设加密操作的费用为每 1 万次操作 0.03 美元,则上述用量大约需要支付 0.07 美元。 如需了解最新价格信息,请参阅 Cloud KMS 价格。

实际上,提取密钥的频率可能会更高或更低,具体取决于访问模式。请仅将这些数字用作估算值。

监控和问题排查

密钥访问问题可能会产生以下影响:

  • 消息传送延迟

  • 发布出错

您可以使用以下指标监控发布和拉取请求错误(按 response_class 和 response_code 分组):

  • topic/send_request_count
  • subscription/pull_request_count
  • subscription/streaming_pull_response_count

StreamingPull 响应的错误率为 100%。这表示数据流已结束,而不是请求失败。如需监控 StreamingPull,请查找 FAILED_PRECONDITION 响应代码。

发布和消息传送可能会因多个原因而失败并显示 FAILED_PRECONDITION 错误。

对于推送订阅,无法直接检测特定于 CMEK 的传送问题。请改用以下方法:

  • 使用 subscription/num_unacked_messages 监控推送订阅积压输入量的大小和存在时长。

  • 监控 subscription/oldest_unacked_message_age 是否存在异常峰值。

  • 使用发布错误和 CMEK 审核日志来发现问题。

停用和重新启用密钥

您可以通过以下两种方法阻止 Pub/Sub 对消息数据进行解密:

虽然这两项操作均不能保证即时撤销访问权限,但 IAM 更改通常会传播得更快。如需了解详情,请参阅 Cloud KMS 资源一致性和访问权限更改传播。

如果 Pub/Sub 无法访问 Cloud KMS 密钥,则使用 StreamingPull 或拉取方法发布和传送消息的操作将失败,并显示 FAILED_PRECONDITION 错误。向推送端点传送消息的操作将停止。要恢复传送和发布,请恢复对 Cloud KMS 密钥的访问。

一旦 Pub/Sub 可以访问 Cloud KMS 密钥,系统就会在 12 小时内继续发布消息,并且在 2 小时内继续传送消息。

虽然 Cloud KMS 间歇性中断(不到 1 分钟)不太可能严重中断发布和传送,但 Cloud KMS 长期不可用会产生与密钥撤消相同的效果。