Foxtable(狐表)用户栏目专家坐堂 → 能帮助把钉钉的加密解密函数进行封装吗?


  共有3394人关注过本帖树形打印复制链接

主题:能帮助把钉钉的加密解密函数进行封装吗?

帅哥哟,离线,有人找我吗?
gudao123456
  1楼 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:四尾狐 帖子:855 积分:6402 威望:0 精华:0 注册:2017/11/21 21:31:00
能帮助把钉钉的加密解密函数进行封装吗?  发帖心情 Post By:2021/8/1 0:12:00 [显示全部帖子]

近日对钉钉接口进行了研究,其他问题都已解决,就差回调函数搞不定致使监听无法进行,不管是直接调用还是封装,直接调用计算签名失败,用工具封装成.dll。但封装不成功(提示钉钉的源代码有错误,命名空间命名不存在或缺失程序集)。老师能否帮助封装钉钉的加解密函数。谢谢!
[此贴子已经被作者于2021/8/1 0:13:27编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
gudao123456
  2楼 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:四尾狐 帖子:855 积分:6402 威望:0 精华:0 注册:2017/11/21 21:31:00
  发帖心情 Post By:2021/8/1 11:34:00 [显示全部帖子]

但需要监听事件啊。比如有新的审批单生成,钉钉告知服务端,服务端作出相应的操作,这个不用钉钉的事件订阅如何能做到呢?谢谢!

我的思路是这样的:有员工发起了审批实例,钉钉通知服务器,服务器进行的判断(这个需要再服务器的数据库查询的,就好比订单系统需要先查库存一样),如果不符合条件,直接拒绝,如果符合条件,进入人工审批流程,当审批流程完成后,如果是审批通过的,钉钉告知服务器,服务器把审批的单据导入系统数据库。这其中有两步需要接到钉钉的通知。杰哥能否给个帮助或别的思路?谢谢!

因为事件订阅,钉钉需要验证网址的正确性,就是像微信的验证信息,用到加密解密函数。狐表封装了微信的,但没有封装钉钉的。我用钉钉官网提供的.cs用vs2017版本生成.dll 不成功,提示 system.txt 命名空间没有命名 json 缺少程序集 没有成功。直接调用蓝版提供的全局代码,又提示计算签名失败。
[此贴子已经被作者于2021/8/1 11:49:46编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
gudao123456
  3楼 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:四尾狐 帖子:855 积分:6402 威望:0 精华:0 注册:2017/11/21 21:31:00
  发帖心情 Post By:2021/8/1 13:26:00 [显示全部帖子]

钉钉开发文档:https://developers.dingtalk.com/document/app/configure-event-subcription/title-dvf-srp-e9i

消息加解密

为了保证数据传输的安全,钉钉在推送订阅事件时,会携带配置的token用来验证事件来源。同时使用该密钥对消息内容做对称加密。

单击这里获取回调加解密类库和对应demo。

钉钉服务器会把msg消息体明文编码成encryptencrypt = Base64_Encode(AES_Encrypt[random(16B) + msg_len(4B) + msg + $key])是对明文消息msg加密处理后的Base64编码。其中:

  • random为16字节的随机字符串。

  • msg_len为4字节的msg长度,网络字节序。

  • msg为消息体明文。

  • key为应用的appKey。

取出返回的JSON中的encrypt字段:

  • 对密文BASE64解码:aes_msg=Base64_Decode(encrypt);

  • 使用AESKey做AES解密:rand_msg=AES_Decrypt(aes_msg);

加解密代码示例如下:

注意

  • 此代码示例的加解密过程依赖DingCallbackCrypto工具类,参见dingtalk-callback-Crypto

  • 示例中的Constant.OWNER_KEY说明如下:

    • 当使用本文档中的方式接收钉钉推送的订阅事件时,是以应用为维度推送的,OWNER_KEY为应用的AppKey,可在开发者后台的应用详情页面中获取。

    • 当使用HTTP回调注册接口方式接收钉钉推送的订阅事件时,是以企业为维度推送的,OWNER_KEY为CorpId。

public Map<String, String> callBack(
                                    @RequestParam(value = "msg_signature", required = false) String msg_signature,
                                    @RequestParam(value = "timestamp", required = false) String timeStamp,
                                    @RequestParam(value = "nonce", required = false) String nonce,
                                    @RequestBody(required = false) JSONObject json) {
    try {
        // 1. 从http请求中获取加解密参数

        // 2. 使用加解密类型
        // Constant.OWNER_KEY 说明:
        // 1、开发者后台配置的订阅事件为应用级事件推送,此时OWNER_KEY为应用的APP_KEY。
        // 2、调用订阅事件接口订阅的事件为企业级事件推送,
        //      此时OWNER_KEY为:企业的appkey(企业内部应用)或SUITE_KEY(三方应用)
        DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(Constant.AES_TOKEN, Constant.AES_KEY, Constant.OWNER_KEY);
        String encryptMsg = json.getString("encrypt");
        String decryptMsg = callbackCrypto.getDecryptMsg(msg_signature, timeStamp, nonce, encryptMsg);

        // 3. 反序列化回调事件json数据
        JSONObject eventJson = JSON.parseObject(decryptMsg);
        String eventType = eventJson.getString("EventType");

        // 4. 根据EventType分类处理
        if ("check_url".equals(eventType)) {
            // 测试回调url的正确性
            bizLogger.info("测试回调url的正确性");
        } else if ("user_add_org".equals(eventType)) {
            // 处理通讯录用户增加事件
            bizLogger.info("发生了:" + eventType + "事件");
        } else {
            // 添加其他已注册的
            bizLogger.info("发生了:" + eventType + "事件");
        }

        // 5. 返回success的加密数据
        Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
        return successMap;

    } catch (DingTalkEncryptException e) {
        e.printStackTrace();
    }
    return null;
}

[此贴子已经被作者于2021/8/1 13:26:56编辑过]

 回到顶部