認證姿勢-Jwt-基礎篇

一、定義
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
Json Web Token簡稱Jwt,是一種開放標準 (RFC 7519),它定義了一種緊湊且自包含的方式,用于在各方之間數(shù)據(jù)作為JSON對象安全地傳輸信息。數(shù)據(jù)信息經(jīng)過數(shù)字簽名,可以被驗證和信任。JWT可以使用秘密(使用 HMAC算法)或使用RSA或 ECDSA的公鑰/私鑰對進行簽名。Jwt中簽名加密解密主要依靠加密令牌和簽名令牌,加密令牌將信息進行加密,避免其他方知道對應聲明的信息內容,簽名令牌驗證加密信息中聲明的完整性,當使用公鑰/私鑰對對令牌進行簽名時,簽名還證明只有持有私鑰的一方才是對其進行簽名的一方 。
二、結構
一個jwt包含以下結構:
Header
Payload
Signature
各個部分以點.進行分隔,xxxx.yyyy.zzzz。
1、Header
頭部由令牌類型Jwt以及簽名使用的加密算法類型組成,例如HMAC SHA256 或 RSA。該部分由Base64Url方式進行編碼。
?{
? ?"alg": "HS256",
? ?"typ": "JWT"
?}2、Payload
負載部分,包含了聲明部分,聲明是對用戶實體信息以及附加數(shù)據(jù)信息的聲明,分為三種類型,registered聲明、public聲明和private聲明。
registered聲明,為一組系列規(guī)則預定義的可用的,可互操作的聲明,例如iss(發(fā)行者)、exp(到期時間)、sub(主題)、aud(受眾)等。聲明名稱僅僅三個字符,在自定義時需要注意該細節(jié)。該部分同樣由Base64Url進行編碼。
public聲明,為使用JWT的人隨意定義,為避免沖突,用戶自定義時,應盡量避開[官方規(guī)范]https://www.iana.org/assignments/jwt/jwt.xhtml中包含的聲明。
private聲明,由同意使用它們的各方之間共享信息而創(chuàng)建的自定義信息。
案例如下:
?{
? ? ?"sub":"testsub",
? ? ?"name":"ggcy",
? ? ?"iat":1516239022
?}需要注意的是,在 Header 和 Payload 中避免存放涉及到私密內容,整體信息防篡改,但是對信息并不負責,數(shù)據(jù)內容的安全性,這里是讀者需要注意的地方。
3、Signature
創(chuàng)建指紋,需要以下幾個部分,Header、Payload、一個秘鑰,其中 Header 和 Payload 都是需要 Base64Url 進行編碼,幾個部分最終由 Header 定義的加密算法進行加密。具體抽象邏輯如下:
?HMACSHA256(
? ?base64UrlEncode(header) + "." +
? ?base64UrlEncode(payload),
? ?secret)案例如下:header
?{
? "alg": "HS256",
? "typ": "JWT"
?}
payload
?{
? "sub": "1234567890",
? "name": "John Doe",
? "iat": 1516239022
?}
signature
?HMACSHA256(
? base64UrlEncode(header) + "." +
? base64UrlEncode(payload),
? your-256-bit-secret
?)
?
?//生成結果如下
?SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
組合Jwt,結構如下:xxx.yyy.zzz,內容每一部分由.,進行間隔。
?eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c如果覺得以上內容過于枯燥,想要更具體的體會對應的各個部分的內容,可以訪問Jwt官方提供的在線Jwt生成頁面,https://jwt.io/#debugger-io,進行嘗試測試。
三、工作流程
1、用戶請求特定的授權鏈接進行認證授權,獲取對應用戶憑證。
2、用戶憑證登錄成功后,用戶能夠獲取到一個帶有 Jwt 的返回結果,獲取到的 Jwt 僅僅是在有效時間內能夠正常使用,操作有效時間,就將失效。
3、當用戶要訪問對應受到權限保護的 Api 和資源時,都需要頭部帶有對應有效的 Jwt ,通常在 Header 中,參數(shù)作為 Authorization ,參數(shù)內置格式為 Beaer {token} 的方式,附帶到當前的請求中。
四、好處和不足
說了工作原理,那對應使用 Jwt 有什么好處?或者說有什么優(yōu)缺點?
首先考慮一個問題,傳統(tǒng)的憑證下發(fā)方式都有哪些?
簡單網(wǎng)絡令牌 (SWT) 和安全斷言標記語言令牌 (SAML)
1、好處
1)結構上
相比Xml,Json的結構更加緊湊,字符串進行編碼時,占用的空間更少。
2)安全上
SWT 只能由使用 HMAC 算法的共享秘密對稱簽名,JWT 和 SAML 令牌可以使用 X.509 證書形式的公鑰/私鑰對進行簽名,使用 Xml 在避免引入隱藏的安全相對于 Json 是更困難的。
3)使用上
Json 解釋器對于大多數(shù)編程語言來說,更加方便,能夠將結構直接映射到對象上,操作上更加便捷。Jwt中攜帶的公開信息,也能為跨系統(tǒng)交互提供一定的輔助操作。
2、不足
1)不是銀彈
Jwt 并沒有解決傳統(tǒng) Session 、 Cookie 、OIDC(OpenId Connect) 等方式的跨域和 XSS 問題。
2)依賴秘鑰加密解密
Jwt的生成和解密都需要依賴于 Secret ,常常需要以硬編碼方式嵌入到系統(tǒng)中(或配置文件),對于秘鑰的管控,影響了系統(tǒng)的安全性指數(shù)。
3)客戶端控制缺失
一旦生成 Jwt 下發(fā)到客戶端,保存在 Jwt 中的信息將對使用者來說,有效期間內,可視為透明,如果想要像 Session 那樣進行遠程控制異常賬戶,就需要使用更多的手段去彌補。
4)冗余的數(shù)據(jù)開銷
本質上,對于 Session 來說,Jwt的數(shù)據(jù)長度是比前者大的,如果不對Payload的長度進行限制,實際長度和內容大小的優(yōu)勢將不復存在。
五、總結
從以上對 Jwt 的學習過程中,可以了解到,Jwt 只是一種在用戶認證授權過程中,采取的一種比較簡單并且防信息篡改的憑證方式,并不是事事都能估計和全面的銀彈,使用時應當依據(jù)實際情況進行選擇。
六、參考鏈接
[1]JWT-JSON WEB TOKEN使用詳解及注意事項:https://cloud.tencent.com/developer/article/1542175 [2] ?Jwt 介紹https://jwt.io/introduction
往期推薦

