应用层加密

Standard Payments 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 会自动从软件包中为您想让其执行的每项操作选择正确的密钥。

通过 JWS 签名进行 JWE 加密

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

请求和响应将是使用“紧凑序列化”选项通过非对称(公钥)加密技术加密的 JWE 令牌。JWE 令牌将包含作为 JWS 令牌的已签名载荷。JWS 也使用非对称密钥;私钥用于签名,公钥用于验证。

发送载荷时,请先对载荷签名,然后再对其进行加密。收到载荷时,请先对其进行解密,然后再验证签名。

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

  • 紧凑序列化。
  • 通过多个 JWE 密钥中的一个解密载荷。
  • 使用管理密钥的 RSA-OAEP、RSA-OAEP-256 或 ECDH-ES 算法。
  • 用于加密内容的 A256GCMA128GCMA128CBC-HS256A256CBC-HS512 算法。
    • 填充在 enc 标头中。
  • 用于标识公钥加密密钥的 kid 标头。
  • 使用 JWE 加密的消息载荷必须使用内容类型“application/jose; charset=utf-8”。

使用 JWS 时,合作伙伴必须支持以下方案:

  • 紧凑序列化。
  • 验证来自多个 JWS 密钥之一的载荷。
  • 用于创建签名的 HS256、HS384、HS512、RS256、RS384、RS512、ES256、PS256、PS384 或 PS512 算法。
  • kid 标头,用于标识私钥签名密钥。

JWE/JWS 字符串将编码为 UTF-8 字符串,其载荷可以是任意字节。

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

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