一、jwt構成
JWT(JSON Web Token)是一種輕量級的身份驗證方案,它具有可擴展性和易於傳輸的特點。JWT由三個部分構成:頭部(header),載荷(payload) 和簽名(signature)。具體來講, JWT的格式為”以點號分隔的三部分”:頭部.載荷.簽名(header.payload.signature)。
頭部包含token的類型(即JWT)以及使用的演算法。例如:
{
"alg": "HS256",
"typ": "JWT"
}
載荷包含JWT的「聲明」,例如使用者id (uid)、 用戶名、過期時間等。例如:
{
"uid": "123456",
"username": "Alice",
"exp": 1621538243
}
簽名部分由前面的兩部分加上一個密鑰組成,用於保證數據的完整性和真實性。例如,如下sign
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
二、jwt公共密匙如何破解
在jwt中,密鑰是一個重要的組成部分,用於保證數據的安全性。一般來講,我們需要將密鑰在伺服器端保存並使用。如果密鑰泄露,攻擊者可能會篡改或偽造有效的token。於是,到底是如何破解密匙的呢?
由於jwt使用三部分組成——header,payload和簽名,我們可以很容易地猜出密鑰,做到對jwt進行驗證。例如,一個具有如下header,payload的JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFt ZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJ f36POk6yJV_adQssw5c
我們可以保存header和payload,而不包含簽名,然後嘗試使用一些最常用的演算法來猜出密鑰。然而,密鑰空間可能非常大,因此這種攻擊顯然是低效的。更好的方法是使用一些已知的密鑰來攻擊,並嘗試重建相關密鑰,或利用一些其他漏洞來獲取密鑰。
三、jwt工具
許多jwt工具可用於幫助我們創建、簽名和驗證token。其中包括:
1、jwt-go
jwt-go是golang的一個JWT的實現庫,它提供了簡單而強大的API,可以用來處理JWT。
使用jwt-go庫非常簡單。首先,我們需要導入包:
import (
"github.com/dgrijalva/jwt-go"
)
然後,我們需要創建一個聲明集合(Claims):
type MyClaims struct {
Example string `json:"example"`
jwt.StandardClaims
}
最後,我們可以使用MyClaims來創建和解析JWT:
// 創建JWT:
func createJwtToken() (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, MyClaims{
Example: "abc",
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
},
})
return token.SignedString([]byte("secret"))
}
// 解析JWT:
func parseJwtToken(tokenString string) (*MyClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte("secret"), nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*MyClaims); ok && token.Valid {
return claims, nil
}
return nil, errors.New("invalid token")
}
2、jwt.io
jwt.io是一個在線查詢、創建、編輯和解析JWT的工具。
你可以在jwt.io上發送一個包含JWT的請求,並獲得對應的解碼數據。此外,你還可以在線創建和編輯一個JWT,選擇不同加密/解密演算法和密鑰等。
四、jwt攻擊手法
由於JWT的安全性不僅取決於密鑰,還取決於生成時間、過期時間等因素,因此攻擊者可以利用各種技術進行攻擊。以下是一些常見的攻擊手法。
1、重放攻擊
重放攻擊是指攻擊者獲得了有效的jwt,並多次使用該jwt進行身份驗證。對於jwt的使用,一般會將jwt的生成時間和過期時間保存到Claims中,用於驗證jwt的有效期。重放攻擊者可以通過在有效期內進行重複使用token的方式,避免重新生成token,從而繞過身份驗證。
2、字典攻擊
字典攻擊是指攻擊者使用密碼字典等工具,通過嘗試所有可能的密鑰來獲取token或解密它。由於token中的簽名取決於密鑰而不是明文,因此只有獲得正確的密鑰才能成功解密token。然而,由於密鑰空間可能非常大,因此這種攻擊大多數時候無法成功。
3、Session劫持
Session劫持是一種攻擊方式,攻擊者在客戶端瀏覽器上安裝惡意代碼,以便於竊取用戶的Session信息,並利用該信息進行非法活動,例如更改用戶的信息、篡改數據等。儘管Session劫持與JWT本身沒有關係,但由於JWT在跨域、分散式等場景下使用得到很好,因此常常被用於替代Session認證。
五、jwt攻擊
儘管JWT是一種流行的身份驗證方式,但它並不是絕對安全的。攻擊者可以通過各種技術來破解JWT,從而達到非法訪問等惡意行為。以下是一些常見的攻擊策略。
1、篡改payload
如果攻擊者可以篡改JWT的payload,那麼他就能夠在未經授權的情況下訪問系統。為了防止這種攻擊,可以在簽名中包含只有伺服器可以生成的內容,例如隨機數、時間戳等。
2、偽造signature
偽造簽名是一種常見的攻擊方式。如果攻擊者獲得了有效的JWT並偽造了簽名,那麼他就可以在未經授權的情況下訪問系統或者獲取系統的數據。為了防止這種攻擊,可以選擇有效的加密演算法,並保護密鑰,避免泄露。
3、重放攻擊
重放攻擊是指攻擊者獲得了有效的jwt並多次使用該jwt進行身份驗證。為了防止這種攻擊,可以增加時間戳,為token設置過期時間等方式。
六、jwt公鑰私鑰
密鑰是JWT的一個重要組成部分。為了進一步保護jwt的安全性,我們可以使用公鑰和私鑰的方式來進行加密和解密。具體來說,使用者使用私鑰對JWT進行簽名,然後將JWT和公鑰一起發送到伺服器,讓伺服器使用公鑰來驗證JWT的有效性。
在jwt-go中,我們可以使用RSA密鑰來進行加密和解密。具體來說,需要使用RSAPrivateKey和RSAPublicKey來載入自己的密鑰對,例如:
// 載入私鑰
privateBytes, err := ioutil.ReadFile("private.pem")
if err != nil {
panic(err)
}
privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateBytes)
if err != nil {
panic(err)
}
// 載入公鑰
publicBytes, err := ioutil.ReadFile("public.pem")
if err != nil {
panic(err)
}
publicKey, err := jwt.ParseRSAPublicKeyFromPEM(publicBytes)
if err != nil {
panic(err)
}
使用密鑰對來創建和驗證JWT:
// Create JWT with RSA256
func createJwtToken() (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodRS256, MyClaims{
Example: "abc",
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
},
})
return token.SignedString(privateKey)
}
// Parse JWT with RSA256
func parseJwtToken(tokenString string) (*MyClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
return publicKey, nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*MyClaims); ok && token.Valid {
return claims, nil
}
return nil, errors.New("invalid token")
}
七、jwt功能
儘管JWT被認為是一種輕量級的身份驗證方案,但它實際上具有豐富的功能。以下是一些常見的功能:
1、自定義聲明
使用者可以在載荷中添加自定義的聲明,例如電子郵件地址、電話號碼等。這些聲明可以由伺服器端進行驗證,以確保所有的聲明都是真實的。
2、過期時間
在生成JWT時,可以設置過期時間,以便在過期後JWT被認為是無效的。在驗證過程中,可以使用過期時間來確保JWT的有效性。
3、JWT的吊銷
使用者可以將jwt的id (jti) 存儲在伺服器端,然後發送帶有JWT的請求時逐個比較JWT的jti,來避免重播攻擊。令牌吊銷通常用於跟蹤或管理 使用客戶端的會話ID一樣。
4、訪問控制
使用者可以在JWT的載荷中包含用戶的許可權,以便伺服器端對數據進行訪問控制。例如,在醫療保健系統中,用戶必須擁有正確的角色和許可權才能查看特定的醫療記錄。
5、跨域支持
由於JWT是基於加密的JSON格式的數據,它具有更好的瀏覽器支持,可以作為跨域身份驗證的完美解決方案。此外,由於JWT只需要通過 HTTP頭或查詢參數傳輸,因此在使用XMLHttpRequest或fetch等類型的ajax請求時更容易使用。
八、jwt公鑰驗簽
在JWT中,我們可以使用公鑰來進行驗證。具體來說,使用者使用私鑰對JWT進行簽名,然後
原創文章,作者:VDOK,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/133208.html
微信掃一掃
支付寶掃一掃