81 lines
3.8 KiB
Python
81 lines
3.8 KiB
Python
import base64
|
|
import hashlib
|
|
|
|
import jmespath
|
|
import xmltodict
|
|
from Crypto.Cipher import AES
|
|
from django.core.handlers.wsgi import WSGIRequest
|
|
from rest_framework.request import Request
|
|
|
|
|
|
class wecom设置接收事件服务器通讯录:
|
|
"""https://work.weixin.qq.com/wework_admin/frame#apps/contactsApi"""
|
|
# 跟认证目录下的功能是一样的(这里是留一个备份)
|
|
token = "bVWt1PEUCG" # url验证的token(当前的值为江苏六果科技有限公司)
|
|
EncodingAESKey = "LS6VsiJA6Vpb3nJlt34vMZFAbuKDJkFuH2KxuEXYuUR" # 配置的解密(当前的值为江苏六果科技有限公司)
|
|
corp_id = "wwbe6369dc26a9d83a" # 企业微信🆔(当前的值为 江苏六果科技有限公司)
|
|
corpsecret = "SIRyum7vQh-Bt36AxnqKMX0HIiE-zkYbjYgSat7reZw" # 企业微信 secret(当前的值为 江苏六果科技有限公司)
|
|
|
|
# phone_secret = "WNxZZdcU3FRS5msq_kHZaaZOBauBEjJZdQV3VrAxu0c" # 通讯录 secret
|
|
|
|
@classmethod
|
|
def post解密推送消息体(cls, msg_content: bytes):
|
|
""""""
|
|
# 从XML中找到Encrypt标签的内容,即加密数据
|
|
xmldict = xmltodict.parse(msg_content.decode())
|
|
Encrypt = jmespath.search(data=xmldict, expression="xml.Encrypt", )
|
|
# 将EncodingAESKey进行Base64解码,并补足填充字符'='
|
|
AESKey = base64.b64decode(cls.EncodingAESKey + '=')
|
|
|
|
# 创建一个AES加密器对象,使用CBC模式和指定的初始化向量(IV)
|
|
cipher = AES.new(key=AESKey, mode=AES.MODE_CBC, IV=AESKey[:16])
|
|
# 对加密数据进行Base64解码
|
|
aes_msg = base64.b64decode(Encrypt)
|
|
# 使用解密器对象解密数据
|
|
de_text = cipher.decrypt(plaintext=aes_msg)
|
|
print(de_text)
|
|
# 去除解密数据地前16个字节的随机字符串
|
|
content = de_text[16:]
|
|
# 解析前4个字节以获取XML内容的实际长度,并将其从网络字节序转换为主机字节序
|
|
# xml_len = socket.ntohl(struct.unpack("I", content[:4])[0])
|
|
xml_len = int.from_bytes(content[:4], byteorder='big')
|
|
# 根据解析出的长度提取实际的XML内容
|
|
xml_content = content[4: xml_len + 4]
|
|
# 打印XML内容
|
|
# 将XML内容解析为字典格式
|
|
as_dict = xmltodict.parse(xml_input=xml_content)
|
|
|
|
# 打印解析后的字典
|
|
return as_dict
|
|
|
|
@classmethod
|
|
def get请求算法(cls, echostr):
|
|
""""""
|
|
AESKey = base64.b64decode(cls.EncodingAESKey + '=')
|
|
aes_msg = base64.b64decode(echostr)
|
|
aes = AES.new(key=AESKey, mode=AES.MODE_CBC, iv=aes_msg[:16])
|
|
de_text = aes.decrypt(plaintext=aes_msg)
|
|
content = de_text[16:] # 去掉前16随机字节
|
|
# 取出4字节的msg_len
|
|
xml_len = int.from_bytes(content[:4], byteorder='big')
|
|
xml_content = content[4: xml_len + 4]
|
|
return xml_content
|
|
|
|
@classmethod
|
|
def get解密验证消息(cls, request: WSGIRequest | Request, ):
|
|
"""接受微信发过来的get请求,拿到参数后解决,并且回复值,结果为验证成功"""
|
|
GET_OBJ = request.query_params
|
|
signature = jmespath.search(data=GET_OBJ, expression="msg_signature", )
|
|
timestamp = jmespath.search(data=GET_OBJ, expression="timestamp", )
|
|
nonce = jmespath.search(data=GET_OBJ, expression="nonce", )
|
|
echostr = jmespath.search(data=GET_OBJ, expression="echostr", )
|
|
# TODO:sorted([token, timestamp, nonce])这是就是对三个参数进行字典排序
|
|
hashstr = ''.join(sorted([cls.token, timestamp, nonce, echostr, ])) # 这是就是对三个参数进行字典排序
|
|
sig = hashlib.new(name="sha1", data=hashstr.encode()).hexdigest()
|
|
if sig == signature:
|
|
ret = cls.get请求算法(echostr)
|
|
s = ret.decode().strip()
|
|
return s
|
|
else:
|
|
raise Exception("没有验yghd成功")
|