python3 jwt(json web token).py

"""
模块:python3 jwt(json web token).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("用户信息已被篡改!")
# 验证通过!
# 用户信息已被篡改!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值