您目前查看的是 Apigee Edge 說明文件。
前往 Apigee X 說明文件。 info
本主題提供 JWT (JSON Web Token) 和 JWS (JSON Web Signature) 的一般資訊,以及 Apigee 代理程式開發人員可能感興趣的 Apigee JWS/JWT 政策。
簡介
JWS 和 JWT 常用於在已連線的應用程式之間共用聲明或判斷。透過 JWS/JWT 政策,Edge API Proxy 可以執行下列操作:
在後兩種情況下,政策也會設定變數,讓其他政策或後端服務本身檢查已驗證的聲明,並根據這些聲明做出決策。
使用「驗證 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 中的聲明。無論 JWS/JWT 是由第三方或 Edge 本身產生,Edge 都會使用 RSA 或 HMAC 演算法驗證 JWS/JWT 的簽章。
- 解碼 JWS/JWT。與「驗證 JWS/JWT」政策搭配使用時,解碼功能最實用,因為在驗證 JWS/JWT 之前,必須先瞭解 JWS/JWT 內憑證 (JWT) 或標頭 (JWS/JWT) 的值。
JWS/JWT 的組成部分
簽署的 JWS/JWT 會將資訊編碼為三個部分,並以英文句點分隔:標頭、酬載和簽章:
header.payload.signature
- 產生 JWS/JWT 政策會建立所有三個部分。
- 「驗證 JWS/JWT」政策會檢查所有三個部分。
- Decode JWS/JWT 政策只會檢查標頭和酬載。
JWS 也支援「分離」格式,可從 JWS 省略酬載:
header..signature
使用分離式 JWS 時,酬載會與 JWS 分開傳送。您可以使用「驗證 JWS」政策的 <DetachedContent> 元素,指定未編碼的原始 JWS 酬載。接著,Verify JWS 政策會使用 JWS 中的標頭和簽名,以及 <DetachedContent> 元素指定的酬載,驗證 JWS。
如要進一步瞭解權杖,以及權杖的編碼和簽署方式,請參閱:
- JWT:IETF RFC7519
- JWS:IETF RFC7515
JWS 和 JWT 的差異
您可以使用 JWT 或 JWS,在已連結的應用程式之間分享聲明或判斷結果。 兩者之間的主要差異在於酬載的表示方式:
- JWT
- 酬載一律為 JSON 物件
- 酬載一律會附加至 JWT
- 憑證的
typ標頭一律會設為JWT
- JWS
- 酬載可採用任何格式,例如 JSON 物件、位元組串流、八位元串流等
- 酬載不必附加至 JWS
由於 JWT 格式一律會使用 JSON 物件代表酬載,因此 Edge 的「產生 JWT」和「驗證 JWT」政策內建支援處理常見的已註冊聲明名稱,例如 aud、iss、sub 等。也就是說,您可以使用「產生 JWT」政策的元素,在酬載中設定這些憑證附加資訊,並使用「驗證 JWT」政策的元素驗證這些值。詳情請參閱 JWT 規格的「已註冊的宣告名稱」一節。
除了支援特定註冊聲明名稱,產生 JWT 政策也直接支援將任意名稱的聲明新增至 JWT。每項聲明都是簡單的名稱/值配對,值可以是數字、布林值、字串、對應或陣列類型。
由於 JWS 可使用任何資料表示法做為酬載,因此您無法將聲明新增至酬載。 Generate JWS 政策支援將任意名稱的聲明新增至 JWS 的標頭。 此外,JWS 政策支援分離式酬載,也就是 JWS 省略酬載。 分離式酬載可讓您分別傳送 JWS 和酬載,且是多項安全標準的必要條件。
使用 JWS 和 JWT 時避免範本注入
為防止未經授權揭露資料,請在使用 GenerateJWT 或 GenerateJWS 政策時,遵循下列指引:
- 避免直接參照使用者輸入內容:請勿在支援範本的
ref屬性中,直接使用不受信任的輸入內容 (例如request.queryparam.*或request.header.*)。 - 清除輸入內容:如果必須在 JWT/JWS 宣告中使用外部資料,請先使用 AssignMessage 政策,從輸入內容中移除所有大括號 (
{ }) 或其他範本字元,再參照該內容。 - 針對字串使用明確的聲明:如果是簡單的字串聲明,請避免使用
type="map"。使用預設的type="string"可避免參照值隱含範本化。 - 請注意驗證和產生政策之間的行為不一致:JWS 和 JWT 產生政策在範本方面,與驗證政策的行為不同。
簽章演算法簡介
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 Web Key Set (JWKS) 驗證 JWS/JWT
驗證已簽署的 JWS/JWT 時,您需要提供與用於簽署權杖的私密金鑰相關聯的公開金鑰。您有兩種方式可將公開金鑰提供給驗證 JWS/JWT 政策:
- 使用實際的公開金鑰值 (通常在流程變數中提供),或
- 使用以 JWKS 包裝的公開金鑰。
關於 JWKS
JWKS 是代表一組 JSON Web Key (JWK) 的 JSON 結構。JWK 是代表加密編譯金鑰的 JSON 資料結構。JWK 和 JWKS 的說明請參閱 RFC7517。請參閱附錄 A 的 JKWS 範例。JSON Web Key Sets 範例
JWKS 結構
RFC7517 說明各金鑰類型 (例如「RSA」或「EC」) 的 JWKS 金鑰元素。舉例來說,視金鑰類型而定,這些參數可能包括:
- 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 的 Proxy
從核發者取得 JWS/JWT 時,核發者通常會在 JWS/JWT 標頭中插入金鑰 ID (或 kid)。金鑰會告知 JWS/JWT 的接收者如何尋找驗證簽署 JWS/JWT 簽名所需的公開或私密金鑰。
舉例來說,假設核發者使用私密金鑰簽署 JWT。「金鑰 ID」會識別要用來驗證 JWT 的相符公開金鑰。公開金鑰清單通常位於某個知名端點,例如:https://www.googleapis.com/oauth2/v3/certs。
這是 Edge (或任何可與 JWKS 搭配使用的平台) 必須執行的基本序列,才能使用含有 JWKS 的 JWS/JWT:
- 檢查 JWS/JWT 標頭,找出金鑰 ID (kid)。
- 檢查 JWS/JWT 標頭,找出簽署演算法 (alg),例如 RS256。
- 從指定核發機構的知名端點 JWKS 擷取金鑰和 ID 清單。
- 從金鑰清單中擷取公開金鑰,並使用 JWS/JWT 標頭中註明的金鑰 ID,以及相符的演算法 (如果 JWKS 金鑰指定演算法)。
- 使用該公開金鑰驗證 JWS/JWT 的簽名。
身為 Edge API Proxy 開發人員,您需要執行下列操作來進行 JWS/JWT 驗證:
- 從指定發卡機構的知名端點擷取金鑰和 ID 清單。您可以在這個步驟中使用服務呼叫政策。
- 在「驗證 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 設計人員,您有責任決定要使用的金鑰;在某些情況下,這可能是固定的硬式編碼金鑰。