JWS 和 JWT 政策總覽

您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件
資訊

本主題提供 Apigee Proxy 開發人員可能會感興趣的 JWT (JSON Web Token) 和 JWS (JSON Web Signature) 和 Apigee JWS/JWT 政策的一般資訊。

簡介

JWS 和 JWT 經常用於在連線的應用程式之間共用憑證附加資訊或斷言。JWS/JWT 政策可讓 Edge API Proxy 執行以下作業:

  • 產生已簽署的 JWTJWS
  • 在 JWS/JWT 中驗證已簽署的 JWTJWS 及憑證附加資訊。
  • 在不驗證簽名的情況下,將已簽署的 JWTJWS 解碼

在後兩種情況中,政策也會設定允許額外政策的變數,或以後端服務本身來檢查已通過驗證的聲明,並依據這些聲明來制定決策。

使用驗證 JWS/JWT 政策時,系統會拒絕無效的 JWS/JWT,並導致錯誤狀況。同樣地,使用解碼 JWS/JWT 政策時,格式錯誤的 JWS/JWT 將導致錯誤狀況。

影片

觀看這部 JWT 簡介短片。雖然這部影片主要用於產生 JWT,但許多概念都與 JWS 相同。

這部短片將詳細說明 JWT 結構。

應用情境

您可以使用 JWS/JWT 政策執行以下作業:

  • 在 Edge Proxy 的 Proxy 或目標端點端產生新的 JWS/JWT。例如,您可以建立 Proxy 要求流程,產生 JWS/JWT 並將其傳回用戶端。或者,您也可以設計 Proxy,使其在目標要求流程中產生 JWS/JWT,然後將其附加至傳送至目標的要求。之後,這些憑證附加資訊可讓後端服務啟用,以便採用進一步的安全性處理作業。
  • 針對傳入用戶端要求、目標服務回應、服務呼叫政策回應或其他來源的 JWS/JWT,驗證及擷取憑證附加資訊。Edge 會驗證 JWS/JWT 上的簽名,無論 JWS/JWT 是由第三方,或 Edge 本身使用 RSA 或 HMAC 演算法產生。
  • 解碼 JWS/JWT。如果與驗證 JWS/JWT 政策搭配使用,必須先知道 JWS/JWT 中的憑證附加資訊 (JWT) 或標頭 (JWS/JWT) 的值,才能驗證 JWS/JWT,才能找到最適合的解碼方式。

JWS/JWT 的一部分

已簽署的 JWS/JWT 會將資訊編碼成三個部分,並以半形句號分隔:標頭、酬載和簽名:

header.payload.signature
  • 產生 JWS/JWT 政策會建立全部三個部分。
  • 驗證 JWS/JWT 政策會檢查全部三個部分。
  • 解碼 JWS/JWT 政策只會檢查標頭和酬載。

JWS 也支援「卸離」detached格式,可以省略 JWS 中的酬載:

header..signature

卸離的 JWS 後,酬載會與 JWS 分開傳送。請使用驗證 JWS 政策的 <DetachedContent> 元素,指定未編碼的原始 JWS 酬載。接著,使用 JWS 中的標頭和簽章,以及 <DetachedContent> 元素指定的酬載驗證 JWS 政策,藉此驗證 JWS。

如要進一步瞭解符記,以及符記的編碼和簽署方式,請參閱:

JWS 和 JWT 之間的差異

您可以使用 JWT 或 JWS 在已連結應用程式之間共用憑證附加資訊或斷言。兩者的主要差異在於酬載的表示法:

  • JWT
    • 酬載一律為 JSON 物件
    • 酬載一律會附加至 JWT
    • 權杖的 typ 標頭一律設為 JWT
  • JWS
    • 酬載能以任何格式表示,例如 JSON 物件、位元組串流、八位元串流等
    • 酬載不需要附加至 JWS

由於 JWT 格式一律使用 JSON 物件代表酬載,因此 Edge Generate JWT 和驗證 JWT 政策內建支援處理常見的註冊憑證名稱,例如 audisssub 等。也就是說,您可以使用「Generate JWT」政策元素,在酬載中設定這些憑證附加資訊,並使用驗證 JWT 政策的元素來驗證這些值。詳情請參閱 JWT 規格的註冊宣告名稱一節。

除了支援特定的註冊憑證名稱之外,Generate JWT 政策也直接支援在 JWT 中新增具有任意名稱的憑證附加資訊。每個憑證附加資訊都是簡單的名稱/值組合,其值可以是類型數字、布林值、字串、地圖或陣列。

由於 JWS 可以使用任何資料表示法來處理酬載,因此您無法在酬載中新增憑證附加資訊。「產生 JWS」政策不支援新增使用任意名稱的憑證附加資訊至 JWS 的標頭。 此外,JWS 政策支援卸離的酬載,其中 JWS 會省略酬載。卸離的酬載可讓您分別傳送 JWS 和酬載,而這需要一些安全性標準的必要性。

關於簽名演算法

JWS/JWT 驗證和 JWS/JWT 產生政策支援 RSA、RSASSA-PSS、ECDSA 和 HMAC 演算法,而且會使用位元強度 256、384 或 512 的 SHA2 總和檢查碼。無論用於簽署 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 Keys (JWK)。JWK 是代表加密編譯金鑰的 JSON 資料結構。RFC7517 說明 JWK 和 JWKS。請參閱附錄 A. JSON 網路金鑰集範例

JWKS 結構

RFC7517 會說明每種金鑰類型的 JWKS 主要元素,例如「RSA」或「EC」。舉例來說,視金鑰類型而定,這些參數可包含:

  • kty - 金鑰類型,例如「RSA」或「EC」。
  • kid (鍵 ID) - 可以是任何任意值 (鍵集內沒有重複的值)。如果傳入的 JWT 包含 JWKS 組合中的金鑰 ID,則政策會使用正確的公開金鑰來驗證 JWS/JWT 簽名。

以下為選用元素及其值的範例:

  • alg - 金鑰演算法。必須與 JWS/JWT 中的簽署演算法相符。
  • use - 如果有,則必須是唯一值。

以下 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",
      }
   ]
}

設計 Proxy 以使用 JWKS

從核發機構取得 JWS/JWT 時,發卡機構通常會將金鑰 ID (或子項) 插入 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. 從 JWS/JWT 標頭註明的金鑰 ID 的金鑰清單中擷取公開金鑰,如果 JWKS 金鑰指定演算法,則擷取比對演算法。
  5. 使用該公開金鑰驗證 JWS/JWT 的簽名。

Edge API Proxy 開發人員必須執行下列操作,才能執行 JWS/JWT 驗證:

  1. 從指定核發者的知名端點擷取金鑰和 ID 清單。您可以在這個步驟中使用服務呼叫政策。
  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) 相符的金鑰,則驗證 JWT 政策會擲回錯誤,且不會驗證 JWT。
  • 如果傳入的 JWT 不採用標頭中的金鑰 ID (kid),則無法將金鑰 ID 與驗證金鑰對應至這個金鑰。

身為 Proxy 設計人員,您必須負責決定要使用的金鑰;在某些情況下,這可能是固定的硬式編碼金鑰。