Files
gitlab-instance-0a899031_ch…/crypto_utils.py
2026-03-31 07:04:37 -05:00

63 lines
2.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import base64
import hashlib
from typing import Tuple
from Crypto.Cipher import AES
BLOCK_SIZE = 32 # PKCS5/PKCS7 padding 使用 32 字节块大小
def pkcs5_unpadding(data: bytes) -> bytes:
pad = data[-1]
if pad < 1 or pad > 32:
return data
return data[:-pad]
def pkcs5_padding(data: bytes) -> bytes:
amount_to_pad = BLOCK_SIZE - (len(data) % BLOCK_SIZE)
return data + bytes([amount_to_pad]) * amount_to_pad
def get_aes_key_and_iv(encoding_aes_key: str) -> Tuple[bytes, bytes]:
"""
encoding_aes_key 是平台给的 43 位字符串,需要先补一个 '=' 再 base64 解码。
得到 32 字节 key前 16 字节为 iv。
"""
aes_key = base64.b64decode(encoding_aes_key + "=")
if len(aes_key) != 32:
raise ValueError("encodingAESKey 无效,解码后长度不是 32 字节")
iv = aes_key[:16]
return aes_key, iv
def aes_decrypt_base64(cipher_b64: str, encoding_aes_key: str) -> str:
aes_key, iv = get_aes_key_and_iv(encoding_aes_key)
cipher_bytes = base64.b64decode(cipher_b64)
cipher = AES.new(aes_key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(cipher_bytes)
decrypted = pkcs5_unpadding(decrypted)
return decrypted.decode("utf-8")
def aes_encrypt_base64(plaintext: str, encoding_aes_key: str) -> str:
aes_key, iv = get_aes_key_and_iv(encoding_aes_key)
data = plaintext.encode("utf-8")
padded = pkcs5_padding(data)
cipher = AES.new(aes_key, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(padded)
return base64.b64encode(encrypted).decode("utf-8")
def calc_signature(token: str, timestamp: int, skill_name: str, intent_name: str, query: str) -> str:
"""
文档签名算法:
str = token + time.Now.Unix + skill_name + intent_name + query
signature = MD5(str) 小写 hex
参考https://developers.weixin.qq.com/doc/aispeech/confapi/thirdapi/thirdapi.html
"""
s = f"{token}{timestamp}{skill_name}{intent_name}{query}"
return hashlib.md5(s.encode("utf-8")).hexdigest()