python处理钉钉回调事件中的消息体加解密

博客介绍了钉钉的回调事件列表,包括通讯录用户、部门及企业相关的各类变更事件。开发第三方企业应用时,回调URL会推送数据,需进行解密,且所有回调要返回加密的'success'字符串。还给出了加解密方法文档,并说明了用Python实现整个处理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

钉钉的回调事件列表:

  • user_add_org : 通讯录用户增加

  • user_modify_org : 通讯录用户更改

  • user_leave_org : 通讯录用户离职

  • org_admin_add :通讯录用户被设为管理员

  • org_admin_remove :通讯录用户被取消设置管理员

  • org_dept_create : 通讯录企业部门创建

  • org_dept_modify : 通讯录企业部门修改

  • org_dept_remove : 通讯录企业部门删除

  • org_remove : 企业被解散

  • org_change : 企业信息发生变更

  • label_user_change :员工角色信息发生变更

  • label_conf_add:增加角色或者角色组

  • label_conf_del:删除角色或者角色组

  • label_conf_modify:修改角色或者角色组

另外,在开发第三方企业应用时,通过回调URL推送suite_ticket。

所有的回调事件发生的时候会向URL POST数据,数据需要解密,解密后为

{
  "SuiteKey": "suitexxxxxx",
  "EventType": "suite_ticket ",
  "TimeStamp": 1234456,
  "SuiteTicket": "adsadsad"
}

然后所有的回调都需要向服务器返回经过加密的字符串'seccess'的json数据,

{
  "msg_signature":"111108bb8e6dbce3c9671d6fdb69d15066227608",
  "timestamp":"1783610513",
  "nonce":"123456",
  "encrypt":"1ojQf0NSvw2WPvW7LijxS8UvISr8pdDP+rXpPbcLGOmIBNbWetRg7IP0vdhVgkVwSoZBJeQwY2zhROsJq/HJ+q6tp1qhl9L1+ccC9ZjKs1wV5bmA9NoAWQiZ+7MpzQVq+j74rJQljdVyBdI/dGOvsnBSCxCVW0ISWX0vn9lYTuuHSoaxwCGylH9xRhYHL9bRDskBc7bO0FseHQQasdfghjkl" // "Random"字段的加密数据
}

 下面介绍一下字符串的加解密。

https://open-doc.dingtalk.com/microapp/faquestions/ltr370,这个是文档给出的加解密的方法。

然后就是使用python将整个过程实现。

from base64 import b64encode, b64decode
from Crypto.Cipher import AES
from hashlib import sha1
import struct, random, 


class prpcrypt():
    def __init__(self, key):
        self.key = key
        self.mode = AES.MODE_CBC
        self.Aec_key = b64decode(self.key + '=')
    
    def encrypt(self, text, key):
        # 加密
        rand_txt = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
        txt = ''.join(random.sample(rand_txt, 16))
        text_len = struct.pack('!i', len(text)).decode()
        crypto = AES.new(self.Aec_key, self.mode, self.key[:16])
        text = txt + text_len + text + key
        text = text + (16-len(text) % 16)*chr(16-len(text)%16)
        ciphertext = crypto.encrypt(text)
        return b64encode(ciphertext).decode().strip()

    def decrypt(self, text):
        # 解密
        crypto = AES.new(self.Aec_key, self.mode, self.key[:16])
        plain_text = crypto.decrypt(b64decode(text))
        raw = plain_text.rstrip(b'\0')
        length = struct.unpack('!i', raw[16:20])[0]
        return raw[20:20+length].decode().strip()
    
    def gen_signature(self, token, timestamp, nonce, encrypt):
        # 获取签名
        sign = sha1(''.join(sorted([token, timestamp, nonce, encrypt])).encode())
        return sign.hexdigest()

然后就是拿到POST的数据然后返回'success'

@csrf_exempt
def callback(request):
    token = 'token'  # 加解密需要用到的token
    aes_key = 'aes_key'  # 数据加密的密钥
    suiteKey = 'suiteKey'
    suiteSecret = 'suiteSecret'
    crypt = prpcrypt(aes_key)
    signature = request.GET.get('signature')
    timestamp = request.GET.get('timestamp')
    nonce = request.GET.get('nonce')
    msg_encrypt = json.loads(request.body, encoding='utf-8').get('encrypt')
    msg_signature = crypt.gen_signature(token, timestamp, nonce, msg_encrypt)
    if signature == msg_signature:
        data = json.loads(crypt.decrypt(text=msg_encrypt))
        
        EventType = data.get('EventType')
        (根据EventType对事件作处理)...

        # encrypt = crypt.encrypt("success", suiteKey)  第三方企业应用
        encrypt = crypt.encrypt("success", corpId)    企业内部应用
        result = json.dumps(dict(
            encrypt=encrypt,
            msg_signature=crypt.gen_signature(token, timestamp, nonce, encrypt),
            nonce=nonce,
            timeStamp=timestamp,
        ))
        return HttpResponse(result)

### 飞书事件回调加密方法及解决方案 对于飞书事件回调中的加密方式,虽然具细节可能未在提供的资料中直接提及,但从其他平台如钉钉和微信支付的实践来看,通常涉及以下几个方面: - **数据传输安全**:为了确保数据在网络上传输的安全性,一般采用HTTPS协议来保障通信过程中的信息安全[^3]。 - **消息签名验证**:类似于钉钉小程序生态中的做法,在接收到飞书发送的消息时,可以通过对接收的内容进行签名验证来确认消息的真实性。这涉及到使用特定算法(如HMAC-SHA256)以及共享的秘密密钥来进行计算并对比签名值。 - **敏感信息加密存储**:针对像aes_key这样的敏感字段,则应采取额外措施加以保护,例如利用对称/非对称加密算法对其进行加密后再保存于数据库或其他持久化介质中;当需要读取这些信息时再解密恢复原始内容[^4]。 - **临时令牌机制**:引入一次性使用的随机字符串作为访问凭证的一部分,可以增加系统的安全性。这种方式可以在一定程度上防止重放攻击等问题的发生[^1]。 ```python import hmac import hashlib def verify_signature(secret, timestamp, nonce, signature): """Verify the message signature.""" sign_str = f"{timestamp}{nonce}{secret}" hash_algorithm = hashlib.sha256 mac = hmac.new( secret.encode('utf-8'), msg=sign_str.encode('utf-8'), digestmod=hash_algorithm ) calculated_signature = mac.hexdigest() return hmac.compare_digest(calculated_signature, signature) ``` 上述代码展示了如何实现一个简单的消息签名验证函数,该函数接收四个参数——`secret`(即预先约定好的秘密密钥),`timestamp`, `nonce` 和 `signature` (来自对方传递的信息头)。通过比较本地生成的哈希值与传入的签名是否一致来判断消息的有效性和真实性。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值