配置消息加密

默认情况下,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 配合工作

使用 CMEK 配置 Pub/Sub 时,该服务会自动使用指定的密钥对所有数据进行加密。根据您的使用模式,使用 Cloud KMS 进行 CMEK 操作可能会产生额外费用。

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

在应用层,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 密钥:

  • 消息存储政策 将消息存储限制为该区域,并且启用了 enforceInTransit
  • 所有发布者和订阅者客户端都使用相同的 区域性端点

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

使用 Pub/Sub 配置 CMEK

您可以手动配置 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

    Google Cloud Cloud Shell 会话随即会在控制台的底部启动,并显示命令行提示符。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
假设价格结构为每 10000 次加密操作的费用是 $0.03,则上述用量的费用大约是 $0.07。 如需了解最新的 价格信息,请参阅Cloud KMS 价格

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

监控和问题排查

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

  • 消息传送延迟

  • 发布出错

您可以使用以下指标监控发布和拉取请求错误(按 response_classresponse_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 间歇性中断(不到一分钟)不太可能严重中断发布和传送,但如果 Cloud KMS 长时间不可用,则相当于撤消密钥。