配置消息加密

默认情况下,Pub/Sub 会使用 Google 管理的加密密钥来加密消息。您无需进行设置或配置,也无需修改服务的访问方式。每封邮件都会在以下状态和层中加密:

在应用层,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 会对消息进行解密。

Pub/Sub 使用 Google Cloud 服务账号访问 Cloud KMS。Pub/Sub 会在内部为每个项目保存该服务账号,该服务账号不会显示在您的服务账号列表中。该服务账号的格式为 service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com。如需让 CMEK 功能发挥作用,您必须在 Identity and Access Management 中向此账号授予 Cloud KMS CryptoKey Encrypter/Decrypter 角色。

配置主题

您可以使用 Google Cloud 控制台或 gcloud 命令行工具配置 CMEK。为了满足前提条件,您必须已经完成以下操作:

请参阅 Cloud KMS 快速入门指南,了解如何完成这些任务。

由于 Pub/Sub 资源是全球性的,因此我们强烈建议您使用全局 Cloud KMS 密钥配置启用了 CMEK 的主题。根据主题发布者和订阅者的位置,使用区域性 Cloud KMS 密钥可能会产生对跨区域网络链接的依赖,而这种依赖其实是不必要的。

使用 Google Cloud 控制台

您可以使用 Google Cloud 控制台主题创建对话框来添加加密密钥。如需了解如何访问该对话框,请参阅 Google Cloud 控制台快速入门

如果您没有看到“选择客户管理的密钥”下拉列表,请确保您已为项目启用了 KMS API。

Google Cloud 控制台:

  • 简化 IAM 配置,同时确保 Pub/Sub 服务账号具有适当的权限。

  • 可让您在主题创建对话框中配置加密。

使用命令行

以下示例说明了如何使用 Google Cloud CLI 为主题配置 CMEK:


   # Grant the Pub/Sub service account the Cloud KMS CryptoKey
   # Encrypter/Decrypter role. This service account is different
   # from the service account you are using to authorize requests to Google Cloud.

   gcloud projects add-iam-policy-binding ${PROJECT_ID} --member=\
      "serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" \
      --role='roles/cloudkms.cryptoKeyEncrypterDecrypter'

   # Create a topic that uses customer-managed encryption, using the
   # --topic-encryption-key argument to specify the Cloud KMS key to use
   # for protecting message data.

   KEY_ID=projects/${PROJECT_ID}/locations/global/keyRings/my-key-ring/cryptoKeys/my-crypto-key
   alias pubsub="gcloud pubsub"
   pubsub topics create $TOPIC_NAME --topic-encryption-key=$KEY_ID

   # Confirm that the topic is configured for customer-managed encryption,
   # indicated by the presence of the kmsKeyName specified on the topic.

   pubsub topics describe $TOPIC_NAME
     

审核日志

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

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

价格和费用

对于以下 Pub/Sub 请求,使用 CMEK 会产生基于 Pub/Sub pricing的 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
假设价格结构(加密操作每 10,000 次操作的费用为 $0.03),上述用量的费用约为 $0.07。如需了解最新的价格信息,请参阅 Cloud KMS 价格

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

监控和问题排查

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

  • 消息传送延迟

  • 发布出错

您可以使用以下metrics监控发布和拉取请求错误(按 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 长期不可用与撤消密钥具有相同的影响。