""" 模塊:python3 jwt(json web token)_base64.urlsafe_b64encode()_urlsafe_b64decode()_hmac.new().py 功能:python3 實現 jwt 用戶驗證。 參考:https://blog.csdn.net/weixin_42193179/article/details/104475173 https://blog.csdn.net/weixin_42193179/article/details/104522302 知識點: 1.加密算法 hmac.new(key, msg=None, digestmod=None) 創建一個新的散列對象(hashing object)並返回它。 key: 哈希的起始鍵。 msg: 如果可用,將立即散列到(be hashed into)對象的起始狀態。 digestmod: 摘要(加密)模式,如SHA1、SHA224、SHA256、SHA384、SHA512、MD5等。 現在,您可以使用它的 update() 方法將任意字符串輸入到對象中, 並且可以通過調用它的 digest() 方法在任何時候請求哈希值。 2.base64.urlsafe_b64encode(s) 使用url和文件系統安全的base64字母表編碼字節。 參數s是一個用來編碼的、類似字節的對象。 結果作爲字節對象返回。 字母表使用'-'而不是 '+' , '_' 而不是'/'。 3.base64.urlsafe_b64decode(s) 使用url和文件系統安全的base64字母表解碼字節。 參數s是一個類似字節的對象或要解碼的ascii字符串。 結果作爲字節對象返回。 如果輸入的字節串被錯誤填充,則會引發binascii.Error。 不在url-safe base-64字母表中的字符,而且不是加 '+' 或斜槓 '/',在填充檢查之前將被丟棄。 字母表使用 '-' 而不是 '+' , '_' 而不是 '/'。 """ import json import time import base64 import hmac # 一、構造(JWT[json web token]) # 1.頭部。 # alg,簽名的算法(algorithm),默認是 HMAC SHA256(寫成 HS256); # typ,令牌(token)的類型(type),JWT令牌統一寫爲JWT。 # 用途:將 header 對象使用 Base64URL 方法編碼成字符串,組成 JWT 結構的第一部分。 header = {"alg": "HS256", "typ": "JWT"} headerStr = json.dumps(header) # print(headerStr) # {"alg": "HS256", "typ": "JWT"} headerB64UrlEncoded = base64.urlsafe_b64encode(headerStr.encode()).decode() print("headerB64UrlEncoded:", headerB64UrlEncoded) # headerB64UrlEncoded: eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9 # 2.負載 # 用來存放實際需要傳遞的數據(非私密)。 # iat, Issued At 簽發時間; nbf,Not Before,生效時間; exp,expiration time,過期時間。 timeStart = time.time() payload = {"iat": timeStart, "nbf": timeStart, "exp": timeStart + 10 * 60} payloadStr = json.dumps(payload) payloadB64UrlEncoded = base64.urlsafe_b64encode(payloadStr.encode()).decode() print("payloadB64UrlEncoded:", payloadB64UrlEncoded) # payloadB64UrlEncoded: eyJpYXQiOiAxNTgyNzgxMTczLjQ3OTYwNjYsICJuYmYiOiAxNTgyNzgxMTczLjQ3OTYwNjYsICJleHAiOiAxNTgyNzgxNzczLjQ3OTYwNjZ9 # 3.簽名 # 密鑰。 secretKey = "gao2gao" msg = headerB64UrlEncoded + "." + payloadB64UrlEncoded signature = hmac.new(secretKey.encode(), msg.encode(), 'SHA256').hexdigest() print("signature:", signature) # signature: e709794583cc31eaaea84281972af97e6c589b88130acd0a692a8ac0b3e169e9 # 4.構造 JWT jwt = msg + "." + signature print("jwt:", jwt) # jwt: eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpYXQiOiAxNTgyNzgxNjcyLjAzOTg3NzIsICJuYmYiOiAxNTgyNzgxNjcyLjAzOTg3NzIsICJleHAiOiAxNTgyNzgyMjcyLjAzOTg3NzJ9.771ebe03d303803d66b298753ad72d5a8be571fa732ecc6d993063893d711947 # 二、驗證 JWT # 1.拆分header, payload, signature。 headerB64UrlEncoded, payloadB64UrlEncoded, signature = jwt.split(".") print(headerB64UrlEncoded, payloadB64UrlEncoded, signature) # eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9 eyJpYXQiOiAxNTgyNzgyMTAxLjExOTk4MTgsICJuYmYiOiAxNTgyNzgyMTAxLjExOTk4MTgsICJleHAiOiAxNTgyNzgyNzAxLjExOTk4MTh9 97eed8ea6656572be18de23a6bf59be013bece092ad1efcc4ff70de47547aa5a header = json.loads(base64.urlsafe_b64decode(headerB64UrlEncoded.encode()).decode()) print("header:", header) # header: {'alg': 'HS256', 'typ': 'JWT'} print(type(header)) # <class 'dict'> # 2.獲取簽名的加密算法。 alg = header['alg'] print("alg:", alg) if alg == 'HS256': alg = 'SHA256' print("alg:", alg) # alg: SHA256 # 3.模擬用戶信息篡改。 payload = json.loads(base64.urlsafe_b64decode(payloadB64UrlEncoded.encode()).decode()) print("payload:", payload) # payload: {'iat': 1582783148.1871371, 'nbf': 1582783148.1871371, 'exp': 1582783748.1871371} # 篡改 payload['iss'] = 'gao' print("payload:", payload) # payload: {'iat': 1582783214.8349812, 'nbf': 1582783214.8349812, 'exp': 1582783814.8349812, 'iss': 'gao'} # 重新 base64編碼。 payloadStr = json.dumps(payload) payloadB64UrlEncoded = base64.urlsafe_b64encode(payloadStr.encode()).decode() # 4.重新簽名(個人理解:不可破解的加密) msg = headerB64UrlEncoded + "." + payloadB64UrlEncoded signature2 = hmac.new(secretKey.encode(), msg.encode(), alg).hexdigest() print("signature2:", signature2) # signature2: e8ff3b911f27428c96feb9fca0af61fc3ff4d233bd69e955ec880eb06619003a if signature == signature2: print("驗證通過!") else: print("用戶信息已被篡改!") # 驗證通過! # 用戶信息已被篡改!
python3 jwt(json web token)_base64.urlsafe_b64encode()_urlsafe_b64decode()_hmac.new().py
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.