Python 使用rsa类库基于RSA256算法生成JWT
jwt
简介
jwt(json web token)
,是为了在网络应用环境间传递声明而执行的一种基于json的开放标准。jwt提供了一种简单、安全的身份认证方法,特别适合分布式站点单点登录、或者是签名。
jwt构成
jwt是由3部分信息组成,分别为header
,payload
,signature
,组合形式为:header.payload.signature
(注意:这里的header
,payload
,signature
都是经过base64加密的值)
header
格式如下:
{ 'typ': 'jwt', # 声明类型 'alg': 'rs256' # 声明加密算法 # rsa signature withsha-256 }
要构成jwt
组成部分之前,需要对其进行base64
加密,得到一字符串,形如:eyj0exaioiaislduiiwgimfszyi6icjsuzi1nij9
payload
payload
用于存放有效信息,可划分为三部分。
-
标准声明
-
公共声明
-
私有声明
标准声明(建议但不强制使用)
-
iss
:issue,jwt
签发者 -
sub
:subject,主题 -
aud
:audience,受众,该jwt所面向的用户 -
exp
:jwt
过期时间戳,单位秒,这个过期时间必须要大于签发时间 -
nbf
:定义在什么时间之前,该jwt
都是不可用的 -
iat
:jwt
签发时间 -
jti
:jwt
的唯一身份标识,主要用来作为一次性token
,从而避免重放攻击。
公共声明
公共声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息。一般不建议添加敏感信息,因为该部分在客户端可解密。
私有声明
私有声明是提供者和消费者所共同定义的声明,一般不建议添加敏感信息,因为该部分在客户端也是可解密。
格式如下
{ "iss":"shouke", "sub":"test_subject", "aud":"tester", "iat":1624499492, "exp":1624535491, "jti":"8nlazrgnxpavmha6eybeth7rt8suwbag", "username":"shouke", "hobby":"unknow" }
同header
一样,要构成jwt
组成部分之前,需要对其进行base64
加密,得到一字符串,形如:
eyjpc3mioiaiy2fzc21hbgwuy29tiiwginn1yii6icjtyw5kesisicjhdwqioiaiy2fzc21hbgwilcaiawf0ijogmtyynti4nziznswgimv4cci6ide2nty4mjmymzusicjqdgkioiaismvrbuxqulpar0hjveh1ze5fdwriuyisicj1c2vybmftzsi6icjzag91a2uilcaiag9iynkioiaidw5rbm93in0=
signature
header
,payload
构成了signature
基础信息,格式为:header.payload
,其中header
和payload
,也是base64
加密后的值。
构成jwt
组成部分之前,需要采用header
中alg
配置对应的算法,对上述基础信息进行加密,然后对加密结果进行base64编码
,得到最终的signature
。
l1thor4+gsksndzwjgdsvcjvwlo7nbrdc6cvhay1pycugbuge6um6mj/so1qrivvoyzk/oafhg9kpsr3/93sj4sjxiyyhlajxfih+6tvi9z72h6a2ko2at//gfdtattjemaf8rlsuu58fgysqn2gjcign8ornyx5s4w5zmz+cjk=
最后,将以上三部分用.
连接起来,得到jwt
,如下
eyj0exaioiaislduiiwgimfszyi6icjsuzi1nij9.eyjpc3mioiaiy2fzc21hbgwuy29tiiwginn1yii6icjtyw5kesisicjhdwqioiaiy2fzc21hbgwilcaiawf0ijogmtyynti4nziznswgimv4cci6ide2nty4mjmymzusicjqdgkioiaismvrbuxqulpar0hjveh1ze5fdwriuyisicj1c2vybmftzsi6icjzag91a2uilcaiag9iynkioiaidw5rbm93in0=.l1thor4+gsksndzwjgdsvcjvwlo7nbrdc6cvhay1pycugbuge6um6mj/so1qrivvoyzk/oafhg9kpsr3/93sj4sjxiyyhlajxfih+6tvi9z72h6a2ko2at//gfdtattjemaf8rlsuu58fgysqn2gjcign8ornyx5s4w5zmz+cjk=
代码实现
import rsa import base64 import json import shortuuid from datetime import datetime, timedelta def make_jwt(): header = { 'typ': 'jwt', # 令牌类型 'alg': 'rs256' # 使用的算法 # rsa signature withsha-256 } header = base64.b64encode(json.dumps(header).encode()).decode() # encode decode 默认使用utf-8 print(header) payload = { "iss":"cassmall.com", "sub":"mandy", "aud":"cassmall", "iat":int(datetime.now().timestamp()), "exp":int((datetime.now()+ timedelta(seconds=31536000)).timestamp()), # jwt过期时间戳,单位秒 "jti":shortuuid.uuid(), "username":"shouke", "hobby":"unknow" } payload = base64.b64encode(json.dumps(payload).encode()).decode() print(payload) signature = genrate_signature(1024, '{header}.{payload}'.format(header=header, payload=payload).encode('utf-8'), 'sha-256') print(signature) return '{header}.{payload}.{signature}'.format(header=header, payload=payload, signature=signature) def genrate_signature(nbits, message, hash_method): (pubkey, privkey) = rsa.newkeys(nbits) if not isinstance(message, bytes): message = message.encode('utf-8') hash = rsa.compute_hash(message, hash_method) return base64.b64encode(rsa.sign(hash, privkey, hash_method)).decode() if __name__ == '__main__': print(make_jwt())
上一篇: Django个人博客系统(1-5)