JWT

JWT是Json Web Token的全稱,它是一種基於JSON的令牌規範,用於在網路上聲明某種主張。 它常被用來傳送與使用者相關的資訊聲明,作為身分驗證、會話處理和存取控制機制的一部分,用於會話追蹤技術。會話追蹤技術是保持HTTP狀態的解決方案,常見的有Cookie,Session等


JWT格式

JWT 內容如下

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.5mhBHqs5_DTLdINd9p5m7ZJ6XD0Xc55kIaCRY5r6HRA

由 3 部分組成:header(標頭),payload(有效負載)和signature(簽名)

header是一個JSON對象,儲存描述資料型別type和簽名演算法alg,例如HSA256,RSA256 {  “alg”: “HS256”,  “typ”: “JWT”}透過 Base64UrlEncode編碼後產生如下內容:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
payload存放一些傳輸的有效聲明,可以使用官方提供的聲明,也可以自訂聲明。 {  “sub”: “1234567890”,  “name”: “John Doe”,  “iat”: 1516239022}透過 Base64UrlEncode編碼後產生如下內容:
eyJzdWIiOiIx…omit…MjM5MDIyfQ
signature是 JWT 的核心部分,構成較為複雜,且無法被反編碼。透過HMACSHA256( base64UrlEncode(header) + “.” +base64UrlEncode(payload), secret )產生如下內容:
5mhBHqs5_DTLdINd9p5m7ZJ6XD0Xc55kIaCRY5r6HRA

一般來說,頒發token的網站會透過對header和payload進行hash處理,並使用秘密簽名金鑰產生簽名。 無論使用何種方法,這個過程都能確保自從token發布以來,網站能夠驗證資料沒有被竄改。

JWT的一些名詞介紹

  • JWS ( JSON Web Signature):指的是簽名過的JWT
  • JWE ( JSON Web Encryption):部分payload經過加密的JWT
  • JWA ( JSON Web Algorithms ):目前JWT所用到的密碼學演算法
  • nonsecure JWT:指定的是當header的簽名演算法被設定為none的時候,該JWT是不安全的,因為所有人都可以修改。


常見的JWA

JWT 最常見的幾種JWA(簽名演算法)為HS256(HMAC-SHA256) 、RS256(RSA-SHA256) 還有 ES256(ECDSA-SHA256)。這三種演算法都屬於訊息簽名演算法,它們產生的簽名都是不可逆的。 它們之間的區別在於訊息簽名和簽名驗證所需的key是不同的。

  • HS256:該演算法使用相同的「secret_key」進行簽署和驗證(對稱加密)。 一旦secret_key洩露,安全性將完全喪失。HS256僅適用於集中式認證,必須由可信任方進行簽署與驗證。這個演算法在傳統的單體應用中得到了廣泛應用,但是在任何分散式的架構中,請不要使用它!
  • RS256:使用RSA私鑰進行簽名,以及RSA公鑰進行驗證。 即使公鑰洩漏,也不會有任何影響,只要確保私鑰的安全即可。只要提供公鑰,RS256可以將驗證任務委託給其他應用程式。
  • ES256:和RS256採用相同的方式進行私鑰簽章和公鑰驗證。 儘管兩種演算法在速度上略有差異,但ES256的簽章長度較短(可節省流量),且與RS256相比,演算法強度相當。

HS256和RS256的簽名差別如下

HS256:
signature = HMACSHA256( base64UrlEncode(header) + "." +base64UrlEncode(payload), secret );
   
RS256:      
signature = RSASHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload), publicKey, privateKey)


JWT header

以下是用戶可控制的參數, 每個都告訴接收伺服器在驗證簽名時要用哪個金鑰

  • JWK ( JSON Web Key):用JSON的格式去裝載各種加解密金鑰資訊;
  • JWKs( JWK set ):將很多金鑰放到一個JSON陣列
  • jku(JSON Web key URL): 提供一個 URL,網站可以從中取得一組包含正確的金鑰。
  • kid(key ID): 提供一個 ID,在有多個金鑰可供選擇的情況下,伺服器可以使用該 ID 來識別正確的金鑰。 根據密鑰的格式,這可能有一個匹配的kid參數。
  • kty (Key Type):金鑰類型。定義使用的加密演算法類型,例如RSA加密或橢圓曲線加密EC

JWK

網站可以使用一個可選的JWK header參數,將其公鑰以JWK格式直接嵌入到令牌本身,如下

{ "kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG", 
"typ": "JWT", 
"alg": "RS256", 
"jwk": {
	"kty": "RSA",
	"e": "AQAB", 
	"kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG", 
	"n": "yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9m" 
} }

JWK規範其他細節可參考https://datatracker.ietf.org/doc/html/rfc7517


JWT相關攻擊技巧可參考以下


refer