应用层加密

Client Side Push Provisioning API 支持使用 PGP 或 JWE 进行应用层加密。

PGP 加密

PGP 是一组标准的加密、解密和签名算法,提供隐私保护和身份验证。

使用 PGP 加密载荷时,合作伙伴必须支持:

  • 使用多个 PGP 密钥加密和解密载荷。
  • 使用多个 PGP 密钥为载荷签名。
  • 验证具有多个签名的载荷,其中任何签名都可以是使用 Google 提供的密钥进行的签名。
  • 网络安全 base64 编码载荷解密。

提供给 Google 的 PGP 公钥必须有一个用于加密的子密钥。子密钥可以独立于主密钥进行轮替。主密钥用于身份验证。私钥必须是 2048(或更多)位的 RSA 密钥,一年内到期,最大生命周期为两年。

在开始开发之前,您需要与 Google 交换 PGP 密钥。在此步骤中,您将生成 PGP 公钥私钥对,向 Google 提供公钥,再从 Google 接收公钥。在开发过程中,您只需交换用于开发以及在生产环境之外进行测试的沙盒密钥。在生产测试和发布之前,您需要再次执行生产密钥交换。

生成新的 PGP 密钥

假设您的系统路径中有 GPG 二进制文件,那么您可以使用以下 POSIX 命令来创建新的密钥对。

$ gpg --full-generate-key

出现提示时,选择一个至少为 2048 位熵并且有效期为 1 到 2 年的 RSA 密钥。此命令应同时创建主密钥(标记为“SC”,由“Signing”的首字母“S”和“Certificate”的首字母“C”组成,表示签名证书)和子密钥(标记为“E”,取自“Encryption”的首字母“E”,表示加密)

PGP 库配置

发送载荷

  1. 在签名时,您应使用 SHA384 作为摘要算法;不要使用 SHA1MD5
  2. 在加密时,您应使用 AES256 作为对称加密算法;不要使用 CAST5IDEA
  3. 在对消息进行加密或签名时,请务必选择具有相应用途的子密钥;请使用 CAN_SIGN 密钥签名,使用 ENCRYPT_COMMS/ENCRYPT_STORAGE 密钥加密

接收载荷

  1. 验证载荷时,请确保您的库支持 SHA384 等现代哈希算法。自 2023 年 5 月 14 日起,Google 将在所有新密钥上使用该算法。
  2. 解密载荷时,请确保您的库支持 AES256 等现代对称加密算法。自 2023 年 5 月 14 日起,Google 将在所有新密钥上使用该算法。

GPG 载荷加密示例

以下命令示例展示了如何在使用 GPG 时选择安全选项。此操作应在用户无权访问私钥或敏感输入文件的可信环境中执行。

gpg --output signed-and-encrypted.pgp \
  --sign --digest-algo SHA384 \
  --encrypt --cipher-algo AES256 \
  --armor \
  --recipient {key_id} \
  input.txt

GPG 会自动从软件包中为您想让其执行的每项操作选择正确的密钥。

JWE 加密

JSON Web Encryption (JWE) 是由 rfc7516 定义的标准,用于在应用层级加密内容。

使用 JWE 加密载荷时,合作伙伴必须支持以下方案:

  • 通过多个 JWE 密钥中的一个解密载荷。
  • 紧凑序列化
  • JWE 压缩(即 zip="DEF")
  • 使用管理密钥的 RSA-OAEP/RSA-OAEP-256 或 ECDH-ES 算法
    • 不建议采用 RSAES-PKCS1-V1_5,但可以接受
  • 用于加密内容的 A256GCM 算法。

私钥必须是 RSA/ECDH-ES 密钥,一年内到期,最大生命周期为两年。所有私钥 ID 必须始终保留在合作伙伴的服务器上,因此所有签名的值都必须在合作伙伴的服务器上进行计算。

客户端和服务器将根据 JSON Web Encryption (JWE) 规范对 JSON 正文进行加密。POST 或响应的整个正文将是一个 JWE 令牌,使用 JWE 的“紧凑序列化”方案。

在开始开发之前,您需要与 Google 交换 JWE 密钥。在此步骤中,您将生成公钥私钥对,向 Google 提供公钥,再从 Google 接收公钥。在开发过程中,您只需交换用于开发以及在生产环境之外进行测试的沙盒密钥。在生产测试和发布之前,您需要再次执行生产密钥交换。

合作伙伴必须支持使用 JWE 压缩(即 zip="DEF")发送和接收消息。请求和响应将使用双向交换的 JWE 密钥通过非对称(公钥)加密技术进行加密。此外,在加密之前对内容进行签名并在解密之后进行验证的情况下,JWS 签名验证可以与 JWE 搭配使用。JWS 也使用非对称密钥;私钥用于签名,公钥用于验证。