注意仅可以在Python3中使用
token及token验证
涉及模块hmac与base64
hmac模块
简介
HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出
典型应用HMAC的一个典型应用是用在“质疑/应答”(Challenge/Response)身份认证中。认证流程:先由客户端向服务器发出一个验证请求。
服务器接到此请求后生成一个随机数并通过网络传输给客户端(此为质疑)。
客户端将收到的随机数提供给ePass,由ePass使用该随机数与存储在ePass中的
与此同时,服务器也使用该随机数与存储在服务器数据库中的该客户密钥进行HMAC-MD5运算,如果服务器的运算结果与客户端传回的响应结果相同,则认为客户端是一个合法用户
安全性
由上面的介绍,我们可以看出,HMAC算法更象是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的HASH算法,安全性主要有以下几点保证:
(1) 使用的密钥是双方事先约定的,第三方不可能知道。作为非法截获信息的第三方,能够得到的信息只有作为“挑战”的随机数和作为“响应”的HMAC结果,无法根据这两个数据推算出密钥。由于不知道密钥,所以无法仿造出一致的响应。
生产token
原理:
通过hmac sha1 算法产生用户给定的key和token的最大过期时间戳的一个消息摘要,将这个消息摘要和最大过期时间戳通过”:”拼接起来,再进行base64编码,生成最终的token
import time
import base64
import hmac
def generate_token(key, expire=3600):
""":param key: str (用户给定的key,需要用户保存以便之后验证token,每次产生token时的key 都可以是同一个key):param expire: int(最大有效时间,单位为s):return: state: str"""
ts_str = str(time.time() + expire)
ts_byte = ts_str.encode("utf-8")
sha1_tshexstr = hmac.new(key.encode("utf-8"), ts_byte, 'sha1').hexdigest()
token = ts_str + ':' + sha1_tshexstr
b64_token = base64.urlsafe_b64encode(token.encode("utf-8"))
return b64_token.decode("utf-8")
ret = generate_token("1234566788")
print(ret)
验证token
原理
将token进行base64解码,通过token得到token最大过期时间戳和消息摘要。判断token是否过期。
如没过期才将 从token中的取得最大过期时间戳进行hmac sha1 算法运算(注意这里的key要与产生token的key要相同),最后将产生的摘要与通过token取得消息摘要进行对比, 如果两个摘要相等,则token有效,否则token无效 。
def certify_token(key, token):
""":param key: str:param token: str:return: boolean"""
token_str = base64.urlsafe_b64decode(token).decode('utf-8')
token_list = token_str.split(':')
if len(token_list) != 2:
return False
ts_str = token_list[0]
if float(ts_str) < time.time():
# token expired
return False
known_sha1_tsstr = token_list[1]
sha1 = hmac.new(key.encode("utf-8"), ts_str.encode('utf-8'), 'sha1')
calc_sha1_tsstr = sha1.hexdigest()
if calc_sha1_tsstr != known_sha1_tsstr:
# token certification failed
return False
# token certification success
return True
key = '1234566788'
token = 'MTUzMTc0NDU2OS43OTEzNjg3OjVkZjllNGIyZDgzMmNlYWU2YmRjOGFhMzk2M2Q4NWJmOGVjZTI5YmE=' certify_token(key, token)