JWS 和 JWT 政策概览

<ph type="x-smartling-placeholder"></ph> 您正在查看 Apigee Edge 文档。
转到 Apigee X 文档
信息

本主题提供有关 JWT(JSON Web 令牌)和 JWS(JSON Web 签名)以及 Apigee JWS/JWT 政策的一般信息,Apigee 代理开发者可能会对这些内容感兴趣。

简介

JWS 和 JWT 通常用于在连接的应用之间共享声明或断言。借助 JWS/JWT 政策,Edge API 代理可以执行以下操作:

  • 生成签名的 JWTJWS
  • 验证签名的 JWTJWS 以及 JWS/JWT 中的声明。
  • 对签名的 JWTJWS 进行解码,而无需验证签名。

在后两种情况中,该政策还设置允许其他政策或后端服务本身的变量,以检查已验证的声明并基于这些声明做出决策。

使用“验证 JWS/JWT”政策时,无效的 JWS/JWT 将被拒绝,并将导致错误状况。同样,在使用“解码 JWS/JWT”政策时,格式错误的 JWS/JWT 也会导致错误状况。

视频

观看一段简短视频以快速了解 JWT。虽然此视频专用于生成 JWT,但其中的许多概念同样适用于 JWS。

观看一个简短视频以详细了解 JWT 结构。

使用场景

您可以使用 JWS/JWT 政策执行以下操作:

  • 在 Edge 代理的代理端或目标端点端生成新的 JWS/JWT。例如,您可以创建一个代理请求流,用于生成 JWS/JWT 并将其返回给客户端。或者,您可以设计代理,使其在目标请求流上生成 JWS/JWT,并将其附加到发送到目标的请求。这些声明随后可用于让后端服务应用进一步的安全处理。
  • 验证并提取从入站客户端请求、从目标服务响应、从 Service Callout 政策响应或从其他来源获得的 JWS/JWT 中的声明。Edge 将 验证 JWS/JWT 上的签名,无论 JWS/JWT 是由第三方还是由 Edge 生成 使用 RSA 或 HMAC 算法。
  • 解码 JWS/JWT。与“验证 JWS/JWT”政策结合使用时,并且必须在验证 JWS/JWT 之前知道 JWS/JWT 内的声明 (JWT) 或标头 (JWS/JWT) 的值时,解码最为有用。

JWS/JWT 的组成部分

签名的 JWS/JWT 将解码按句点分隔的三部分中的信息:标头、载荷和签名:

header.payload.signature
  • “生成 JWS/JWT”政策将创建所有三个部分。
  • “验证 JWS/JWT”政策会检查所有三个部分。
  • “解码 JWS/JWT”政策仅检查标头和载荷。

JWS 还支持忽略 JWS 中的载荷的分离格式:

header..signature

对于分离的 JWS,载荷与 JWS 分开发送。您可以使用“验证 JWS”政策的 <DetachedContent> 元素来指定未经编码的原始 JWS 载荷。接着,“验证 JWS”政策使用 JWS 中的标头和签名以及 <DetachedContent> 元素指定的载荷来验证 JWS。

如需详细了解令牌及其编码方式和签名,请参阅:

JWS 和 JWT 之间的差异

您可以使用 JWT 或 JWS 在连接的应用之间共享声明或断言。两者之间的主要区别在于载荷表示法:

  • JWT
    • 载荷始终是一个 JSON 对象
    • 载荷始终附加到 JWT
    • 令牌的 typ 标头始终设置为 JWT
  • JWS
    • 载荷可通过任何格式(例如 JSON 对象、字节流、八位字节流等)表示。
    • 无需将载荷附加到 JWS

由于 JWT 格式始终使用 JSON 对象来表示载荷,因此 Edge Generate JWT 和验证 JWT 政策已内置支持处理常见的注册声明名称,例如 audisssub 等。这意味着您可以使用“生成 JWT”政策的元素在载荷中设置这些声明,以及使用“验证 JWT”政策的元素验证其值。如需了解详情,请参阅 JWT 规范的已注册声明名称部分。

除了支持某些已注册声明名称之外,“生成 JWT”政策和直接支持向 JWT 添加任意名称的声明。每个声明都是一个简单的名称/值对,其中值可以是数字、布尔值、字符串、映射或数组等类型。

由于 JWS 可以使用载荷的任何数据表示法,因此您无法向载荷添加声明。“生成 JWS”政策支持将任意名称的声明添加到 JWS 标头。此外,JWS 政策支持分离的载荷,其中 JWS 会忽略载荷。通过分离的载荷,您可以单独发送 JWS 和载荷,并且若干安全标准需要分离的载荷。

关于签名算法

JWS/JWT 验证和 JWS/JWT 生成政策支持使用位强度 256、384 或 512 的 SHA2 校验和的 RSA、RSASSA-PSS、ECDSA 和 HMAC 算法。无论用于 JWS/JWT 签名的算法是什么,JWS/JWT 解码政策都有效。

HMAC 算法

HMAC 算法依赖于共享密钥(称为密钥)来创建签名(也称为 JWS/JWT 签名),以及验证签名。

密钥长度下限取决于算法的位强度:

  • HS256:密钥长度下限为 32 个字节
  • HS386:密钥长度下限为 48 个字节
  • HS512:密钥长度下限为 64 个字节

RSA 算法

RSA 算法使用公钥/私钥对进行加密签名。使用 RSA 签名时,签名方使用 RSA 私钥进行 JWS/JWT 签名,验证方使用匹配的 RSA 公钥验证 JWS/JWT 上的签名。密钥没有大小要求。

RSASSA-PSS 算法

RSASSA-PSS 算法是 RSA 算法的更新版。与 RSS 类似,RSASSA-PSS 使用 RSA 公钥/私钥对进行加密签名。密钥的格式与 RSS 相同。签名方使用私钥进行 JWS/JWT 签名,验证方使用匹配的公钥验证 JWS/JWT 上的签名。密钥没有大小要求。

ECDSA 算法

椭圆曲线数字签名算法 (ECDSA) 算法是带 P-256、P-384 和 P-521 曲线的椭圆曲线加密算法。使用 ECDSA 算法时,算法会确定您必须指定的公钥和私钥类型:

算法 曲线 密钥要求
ES256 P-256 从 P-256 曲线生成的密钥(也称为 secp256r1 或 prime256v1)
ES384 P-384 从 P-384 曲线生成的密钥(也称为 secp384r1)
ES512 P-521 从 P-521 曲线生成的密钥(也称为 secp521r1)

密钥加密算法

JWS/JWT 政策支持 OpenSSL 支持的所有密钥加密算法。

使用 JSON 网络密钥集 (JWKS) 验证 JWS/JWT

验证签名的 JWS/JWT 时,您需要提供与用于令牌签名的私钥关联的公钥。您可以通过以下两个选项为验证 JWS/JWT 政策提供公钥:

  • 使用实际公钥值(通常在流变量中提供),或者
  • 使用封装在 JWKS 中的公钥。

关于 JWKS

JWKS 是一个 JSON 结构,表示一组 JSON Web 密钥 (JWK)。JWK 是一个 JSON 数据结构,表示加密密钥。RFC7517 介绍了 JWK 和 JWKS。请参阅附录 A 中的 JKWS 示例。JSON Web 密钥集示例

JWKS 结构

RFC7517 介绍了每种密钥类型的 JWKS 密钥元素,例如“RSA”或“EC”。例如,根据密钥类型,这些参数可能包括:

  • kty - 密钥类型,如“RSA”或“EC”。
  • kid(密钥 ID)- 可以是任意值(密钥集中没有重复项)。如果入站 JWT 包含 JWKS 集中存在的密钥 ID,则该政策将使用正确的公钥来验证 JWS/JWT 签名。

下面是可选元素及其值的示例:

  • alg - 密钥算法。它必须与 JWS/JWT 中的签名算法相匹配。
  • use - 如果存在,必须是 sig。

以下 JWKS 包含必需的元素和值,并且在 Edge 上有效(来自 https://www.googleapis.com/oauth2/v3/certs):

{  
   "keys":[  
      {  
         "kty":"RSA",
         "alg":"RS256",
         "use":"sig",
         "kid":"ca04df587b5a7cead80abee9ea8dcf7586a78e01",
         "n":"iXn-WmrwLLBa-QDiToBozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt7-V7KDjCq0_Nkd-X9rMRV5LKgCa0_F8YgI30QS3bUm9orFryrdOc65PUIVFVxIwMZuGDY1hj6HEJVWIr0CZdcgNIll06BasclckkUK4O-Eh7MaQrqb646ghFlG3zlgk9b2duHbDOq3s39ICPinRQWC6NqTYfqg7E8GN_NLY9srUCc_MswuUfMJ2cKT6edrhLuIwIj_74YGkpOwilr2VswKsvJ7dcoiJxheKYvKDKtZFkbKrWETTJSGX2Xeh0DFB0lqbKLVvqkM2lFU2Qx1OgtTnrw",
         "e":"AQAB"
      },
      {
          "kty":"EC",
          "alg":"ES256",
          "use":"enc",
          "kid":"k05TUSt7-V7KDjCq0_N"
          "crv":"P-256",
          "x":"Xej56MungXuFZwmk_xccvsMpCtXmqhvEEMCmHyAmKF0",
          "y":"Bozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt",
      }
   ]
}

将代理设计为使用 JWKS

从颁发者获取 JWS/JWT 时,颁发者通常会将密钥 ID(或 kid)插入 JWS/JWT 标头。密钥会告知 JWS/JWT 的接收人如何查找验证签名的 JWS/JWT 上的签名所需的公钥或密钥。

例如,假设颁发者使用私钥进行 JWT 签名。“密钥 ID”标识用于验证 JWT 的匹配公钥。公钥列表通常在某些已知端点提供,例如:https://www.googleapis.com/oauth2/v3/certs

这是 Edge(或支持 JWKS 的任何平台)执行的基本顺序 使用具有 JWKS 的 JWS/JWT:

  1. 检查 JWS/JWT 标头以查找密钥 ID (kid)。
  2. 检查 JWS/JWT 标头以查找签名算法 (alg),例如 RS256。
  3. 从给定颁发者的已知端点的 JWKS 中检索密钥和 ID 列表。
  4. 如果 JWKS 密钥指定了算法,则从具有 JWS/JWT 标头中所述的密钥 ID 和匹配算法的密钥列表中提取公钥。
  5. 使用该公钥验证 JWS/JWT 上的签名。

作为 Edge API 代理开发者,您需要执行以下操作来执行 JWS/JWT 验证:

  1. 从给定颁发者的已知端点检索密钥和 ID 列表。您可以在此步骤中使用 Service Callout 政策。
  2. 在“验证 JWS/JWT”政策中,在 <Source> 元素中指定 JWS/JWT 的位置,而在 <PublicKey/JWKS> 元素中指定 JWKS 载荷。例如: 针对 VerifyJWT 政策:
    <VerifyJWT name="JWT-Verify-RS256">
        <Algorithm>RS256</Algorithm>
        <Source>json.jwt</Source>
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
        <PublicKey>
            <JWKS ref="public.jwks"/>
        </PublicKey>
        <Subject>apigee-seattle-hatrack-montage</Subject>
        <Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
        <Audience>urn://c60511c0-12a2-473c-80fd-42528eb65a6a</Audience>
        <AdditionalClaims>
            <Claim name="show">And now for something completely different.</Claim>    
        </AdditionalClaims>
    </VerifyJWT>
    

“验证 JWT”政策将执行其他所有操作:

  • 如果在 JWKS 中未找到含与 JWT 中断言的密钥 ID (kid) 匹配的密钥 ID 的密钥,则“验证 JWT”政策会抛出错误,并且不会验证 JWT。
  • 如果入站 JWT 未包含标头中的密钥 ID (kid),则无法执行此 keyid-to-verification-key 映射。

作为代理设计者,您需负责确定要使用的密钥;在某些情况下,这可能是经过硬编码的固定密钥。