尝试写一个基于网页版的python-cli自用客户端。
登录偷懒使用selenium搞定,然而发现无论post什么返回json提示鉴权失败
经过排查发现是一个名为CMS-SIGN的header起到验证作用
CMS-SIGN:1597186314153,hhixIlynVVT6FCaD,2B6714788235D616B01349BA234ADBFA
第一项明显是Unix时间戳,第二项是16位随机字母数字串。
第三项就是需要根据post内容,时间戳和字符串生成的密码
通过浏览器逐步运行发现CMS-SIGN内容是由一个名为getSign的function生成的。
源代码如下
参数:
e:POST请求的内容,整个json payload
t:懒得分析所以不明,一般直接把None扔进去就行
n:13位Unix时间戳,比如:"1597114116005"
a:16个随机大写字母数字组合,比如“9iWRRehE60XOGEMl”
返回内容:用于CMS-SIGN最后一项的字符串
getSign: function(e, t, n, a) {
var r = "";
function i(e) {
var t = [];
for (var n in e) if (e[n] || 0 === e[n] || "0" === e[n] || !1 === e[n]) if (e[n] instanceof Object && !(e[n] instanceof Array)) {
if (e[n] !== {} && 0 !== Object.keys(e[n]).length) {
var a = "{".concat(i(e[n]), "}"),
o = n + "=" + a;
t.push(o)
}
} else if (e[n] instanceof Array) {
var r = e[n];
if (0 !== r.length) {
var s = "";
for (var u in r) r[u] instanceof Object ? s = "".concat(s, "{").concat(i(r[u]), "}") : s += r[u],
u < r.length - 1 && (s += ",");
var c = n + "=" + s;
t.push(c)
}
} else {
if ("string" === typeof e[n] && "" === e[n].trim()) continue;
var A = n + "=" + e[n];
t.push(A)
}
return 0 !== t.length ? (t = t.sort(), t.join("&")) : ""
}
var s = Object.assign({},
t, e),
u = i(s);
return r = u + (u ? "&": "") + "key=" + o()(n + ":" + a),
r = o()(r).toUpperCase(),
r
}
很明显代码经过混淆读起来非常头痛,于是打算python上使用execjs直接运行
然而这段代码缺少了 o()这个function的声明,运行起来肯定会报错
又经过逐步运行发现o()其实只是一个md5码生成。
用node.js 的md5-node代替
于是经过修改后的代码成为
function getSign(e, t, n, a) {
var r = "";
var md5=require('md5-node');
function i(e) {
var t = [];
for (var n in e) if (e[n] || 0 === e[n] || "0" === e[n] || !1 === e[n]) if (e[n] instanceof Object && !(e[n] instanceof Array)) {
if (e[n] !== {} && 0 !== Object.keys(e[n]).length) {
var a = "{".concat(i(e[n]), "}"),
o = n + "=" + a;
t.push(o)
}
} else if (e[n] instanceof Array) {
var r = e[n];
if (0 !== r.length) {
var s = "";
for (var u in r) r[u] instanceof Object ? s = "".concat(s, "{").concat(i(r[u]), "}") : s += r[u],
u < r.length - 1 && (s += ",");
var c = n + "=" + s;
t.push(c)
}
} else {
if ("string" === typeof e[n] && "" === e[n].trim()) continue;
var A = n + "=" + e[n];
t.push(A)
}
return 0 !== t.length ? (t = t.sort(), t.join("&")) : ""
}
var s = Object.assign({},
t, e),
u = i(s);
return r = u + (u ? "&": "") + "key=" + md5(n + ":" + a),
r = md5(r)
r = r.toUpperCase(),r
}
跑了一下得出结果没问题
你好,最近想做和彩云的自动转发功能,看了你们的文章,很受鼓舞,但签名算法怎么也通不过,不知道是和彩云改变算法了,还是我的算法有问题。
麻烦您核实一下:
1、和彩云的签名算法未改变。
2、请提供一个,加密过程的中间数据及加密结果值,以便检查我的算法是否正确。
谢谢!!!
终于解决了!
和彩云没有更新算法,你我在md5加密过程中出了点问题,
第一次加密 md5(n + “:” + a),我把结果输入为大写格式,
所以导致之前一致鉴权失败。
现通过fillder替换 js文件,输入加密过程的值,发现了问题所在。
感谢楼主提供的思路,开始的时候完全没有方向,看了你的文章后,就简单多了。
能否实现和彩云的自动上传?
现在卡在本地文件的选择上,没有找到相关的接口
这个我不太清楚,我发现网页端接口上传最大只能2G后就没继续弄了。