open-dingtalk / dingtalk-callback-crypto Goto Github PK
View Code? Open in Web Editor NEW钉钉回调加解密类库和对应demo
钉钉回调加解密类库和对应demo
测试日志都能输出。。保存就是失败
补充:使用返回的getEncryptedMap数据进行测试返回的是success
补充2:既然是success那么考虑返回格式问题 测试发现 返回successMap:{"msg_signature":"8207a0ae016d1847f7f1d05a62b9b8a84b13dd43","encrypt":"BCtCbxMLXZNAlTNoMraFDhFWJ8l78y/L8/kGvAytjMqUdIiYmdz13Uk04+FviogTgo8P9rXaLl66pkj3uCziHg==","timeStamp":"749","nonce":"5418emcCHwlW5khH"} 格式是正确的
采用了不同方式返回对象 都是不行!!!
建议升级更新加解密
https://github.com/WeiKKJ/DingTalk-Callback-Crypto
翻译自python3版本
如题,官方文档中给出的加解密类是DingCallbackCrypto,但是回调的示例demo用的是DingTalkEncryptor,二者的解密数据并不一致
前提:
钉钉第三方企业应用对接 SyncHTTP 推送,设置 aes_key,此 aes_key 与回调处理接口中使用的 aes_key 不一致时,在对回调的文本进行 decrypt 时可能发生内存溢出。
原因:
String decrypt(String text) 函数进行处理时,在获得
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int plainTextLength = Utils.bytes2int(networkOrder);
之后,在双方 aes_key 不一致时,解析出来的 plainTextLength 可能会为复数或较大的 int 值,在下一步
plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLength), CHARSET);
未对 plainTextLength 长度进行判断,可能导致 java.lang.IllegalArgumentException
(plainTextLength为复数)或 java.lang.OutOfMemoryError
(plainTextLength为较大正数)异常发生。
异常实例:
paramMap:{signature=bee373eadbee717eb154674c2caec6f4d1d73645, msg_signature=bee373eadbee717eb154674c2caec6f4d1d73645, timestamp=1656056612322, nonce=IqHAQ7r5}
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1006)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
其他审批、打卡等事件都能收到回调,但加班事件收不到,可能什么问题?
def encrypt(self, content):
"""
加密
:param content:
:return:
"""
msg_len = self.length(content)
content = ''.join([self.generateRandomKey(16) , msg_len.decode() , content , self.key])
contentEncode = self.pks7encode(content)
iv = self.aesKey[:16]
aesEncode = AES.new(self.aesKey, AES.MODE_CBC, iv)
aesEncrypt = aesEncode.encrypt(contentEncode)
return base64.encodebytes(aesEncrypt).decode('UTF-8')
要调整成如下才能正常运行
content = ''.join([self.generateRandomKey(16) , content , self.key])
content = content[:16] + msg_len + content[16:]
将第87行改为以下代码
aesEncrypt = aesEncode.encrypt(contentEncode.encode())
目前测试jdk11 和 jdk17是可以完美解决 jdk12-16没有测试过,
进入jdk目录 conf -> security -> policy -> limited ->default_local.policy
修改default_local.policy 文件
将 permission javax.crypto.CryptoPermission *, 128; 这一行
改为permission javax.crypto.CryptoPermission *, 512; 保存即可解决 版本Illegal key size的问题
前提:
钉钉第三方企业应用对接 SyncHTTP 推送,设置 aes_key,此 aes_key 与回调处理接口中使用的 aes_key 不一致时,在对回调的文本进行 decrypt 时可能发生内存溢出。
原因:
String decrypt(String text) 函数进行处理时,在获得
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int plainTextLength = Utils.bytes2int(networkOrder);
之后,在双方 aes_key 不一致时,解析出来的 plainTextLength 可能会为复数或较大的 int 值,在下一步
plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLength), CHARSET);
未对 plainTextLength 长度进行判断,可能导致 java.lang.IllegalArgumentException
(plainTextLength为复数)或 java.lang.OutOfMemoryError
(plainTextLength为较大正数)异常发生。
异常实例:
paramMap:{signature=bee373eadbee717eb154674c2caec6f4d1d73645, msg_signature=bee373eadbee717eb154674c2caec6f4d1d73645, timestamp=1656056612322, nonce=IqHAQ7r5}
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1006)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
报错代码 cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
DingCallbackCrypto$DingTalkEncryptException: 计算解密文字错误
jdk版本 -> 17
Java版本的加密类中有如下代码
static {
try {
Security.setProperty("crypto.policy", "limited");
RemoveCryptographyRestrictions();
} catch (Exception ignored) {
}
}
导致回调解密时报错,找不到256的 provider
将上面的limited修改为unlimited就好了
其它版本的jdk没有测试过,看文档好像是jdk8开始支持crypto.policy配置,为什么要设置成limited呢
前几天好好的,今天2021.6.7就报错了。msg_signature , sign 这俩有时候相等有时候不等
e67d6e5d3895d19e5441ee35ec0abf6aa4735300 e67d6e5d3895d19e5441ee35ec0abf6aa4735300
{'CorpId': 'dingc5898d74ea40425facaaa37764f94726', 'EventType': 'user_modify_org', 'UserId': ['manager5091'], 'OptStaffId': 'manager5091', 'TimeStamp': '1623060875680'}
ef2292239bf57e0e4a653ab808b9b450f6e9485b ef2292239bf57e0e4a653ab808b9b450f6e9485b
{'CorpId': 'dingc5898d74ea40425facaaa37764f94726', 'EventType': 'user_modify_org', 'UserId': ['manager5091'], 'OptStaffId': 'manager5091', 'TimeStamp': '1623060875733'}
10.0.3.189 - - [07/Jun/2021 18:14:35] "POST /getcallback?signature=e67d6e5d3895d19e5441ee35ec0abf6aa4735300&msg_signature=e67d6e5d3895d19e5441ee35ec0abf6aa4735300×tamp=1623060875680&nonce=6clubcaE HTTP/1.1" 200 -
a2db01cb3705a585c6b74b24e6bb25ba6a8c4998 5cfffa86aa457189dcd4b9287b26683f7e63541f
[2021-06-07 18:14:35,757] ERROR in app: Exception on /getcallback [POST]
Traceback (most recent call last):
File "D:\dingOa\lib\site-packages\flask-2.0.0-py3.7.egg\flask\app.py", line 2051, in wsgi_app
response = self.full_dispatch_request()
File "D:\dingOa\lib\site-packages\flask-2.0.0-py3.7.egg\flask\app.py", line 1501, in full_dispatch_request
rv = self.handle_user_exception(e)
File "D:\dingOa\lib\site-packages\flask-2.0.0-py3.7.egg\flask\app.py", line 1499, in full_dispatch_request
rv = self.dispatch_request()
File "D:\dingOa\lib\site-packages\flask-2.0.0-py3.7.egg\flask\app.py", line 1485, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "D:/dingOa/api.py", line 23, in callback
decryptMsg = dingCrypto.getDecryptMsg(arg['msg_signature'], arg['timestamp'], arg['nonce'], jsondata['encrypt'])
File "D:\dingOa\DingCallbackCrypto.py", line 53, in getDecryptMsg
raise ValueError('signature check error')
ValueError: signature check error
pycrypto已经是8年前的包了,现在在维护的加密包为pycryptodome。导入名不变,使用方式也没有大的区别。应该是该一行注释的事情
前提:
钉钉第三方企业应用对接 SyncHTTP 推送,设置 aes_key,此 aes_key 与回调处理接口中使用的 aes_key 不一致时,在对回调的文本进行 decrypt 时可能发生内存溢出。
原因:
String decrypt(String text) 函数进行处理时,在获得
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int plainTextLength = Utils.bytes2int(networkOrder);
之后,在双方 aes_key 不一致时,解析出来的 plainTextLength 可能会为复数或较大的 int 值,在下一步
plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLength), CHARSET);
未对 plainTextLength 长度进行判断,可能导致 java.lang.IllegalArgumentException
(plainTextLength为复数)或 java.lang.OutOfMemoryError
(plainTextLength为较大正数)异常发生。
异常实例:
paramMap:{signature=bee373eadbee717eb154674c2caec6f4d1d73645, msg_signature=bee373eadbee717eb154674c2caec6f4d1d73645, timestamp=1656056612322, nonce=IqHAQ7r5}
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1006)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
Prpcrypt 这个类 的196行 问题 导致 有一行的substr() 这个函数的第一个参数是空。
原因是Prpcrypt 这个类没有 __construct 构造函数 然后其他类使用这个类直接 new Prpcrypt($this->m_encodingAesKey)
28行 38行 83行
修改DingCallbackCrypto3.py文件中的 encrypt函数
把
contentEncode = self.pks7encode(content)
改为
contentEncode = self.pks7encode(content).encode('utf-8')
即后面加个.encode('utf-8')
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.