赞
踩
#!/usr/bin/env python # -*- coding:utf-8 -*- import base64 import binascii import hashlib import struct import random import time from Crypto.Cipher import AES SALTS = ["00000000000000000000000000000000", "11111111111111111111111111111111", "22222222222222222222222222222222", "33333333333333333333333333333333", "44444444444444444444444444444444", "55555555555555555555555555555555", "66666666666666666666666666666666", "77777777777777777777777777777777", "88888888888888888888888888888888", "99999999999999999999999999999999"] ENV = { 'dev': 1, 'test': 2, 'stg': 3, 'prod': 4, } # 注意业务字段event_id,为长度为32位的16进制字符串 def generate_ticket(env: str, account_id: int, event_id: str): env_int = ENV[env] create_time = int(time.time()) expire_time = create_time + 2 * 60 * 60 # ticket有效期2小时 first_char = ord(event_id[0]) salt = SALTS[abs(first_char % len(SALTS))] event_type = 1 # 事件类型(业务字段) # account_id + event_id + salt 用于生成AES key和iv(GCM使用nonce) message = str(account_id) + event_id + salt hash_str = hashlib.sha256(message.encode('utf-8')).digest() length = int(len(hash_str) / 2) # 前16字节作为key aes_key = hash_str[:length] # 后16字节作为iv(GCM为nonce) aes_iv = hash_str[length:] cipher = AES.new(aes_key, AES.MODE_GCM, aes_iv) digest = str(account_id) + event_id + str(create_time) + str(expire_time) + str(env_int) + str(event_type) + salt digest_sha = hashlib.sha256(digest.encode('utf-8')).digest() # 待加密字符串由以下参数拼接而成,各字段占用的比特数依次为“i16siibb2s4s” # binascii.unhexlify(event_id) 等价于 int(event_id, 16).to_bytes(length=16, byteorder='big') sensitive_data = struct.pack(">i16siibb2s4s", account_id, binascii.unhexlify(event_id), create_time, expire_time, env_int, event_type, random.randbytes(2), digest_sha[-4:]) params, tag = cipher.encrypt_and_digest(sensitive_data) base64_data = params + tag return base64.b64encode(base64_data).decode('utf-8') if __name__ == '__main__': print('Token_' + generate_ticket('dev', 88888888, 'ffffffffffffffffffffffffffffffff'))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。