2016/09/29 :
理清了
rsa
的步骤,所以自己写了一个。加密思路更清晰明了。
2016/09/24 :
闲着没事,又玩起了模拟登录。距离上一次写模拟登录QQ
已经过去很久了。
抓包
是的,一切分析源自于抓包。
这是登录时,浏览器提交的请求参数。很明显,我们需要知道params
和encSecKey
是怎么来的。
分析JS源码
我们现在浏览器里搜索params
,然后成功的找到了。为了方便操作,我们把它整个复制到本地文件中。
从上面的截图我可以知道,我们需要的参数来自于window.asrsea
这个函数。
中间省略我漫长的查找、分析和验证的过程。我们来直奔主题吧。
先看传入的第一个参数JSON.stringify(bl)
。
bl
在不同的请求下会有不同的值。这里我只列出它在登录时的值。
const bl = {
username: '帐号',
password: crypto.createHash('md5').update('密码').digest('hex'),
rememberLogin: true,
csrf_token: ''
}
关于后面的三个参数其实都是定值。感兴趣,可以自行推演分析。
//bbZ(['流泪', '强'])
const x = '010001'
//bbZ(Ka.md)
const y = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
//bbZ(["爱心", "女孩", "惊恐", "大笑"])
const z = '0CoJUm6Qyw8W8jud'
好的,至此,我们所需要的参数都有了。那么这个window.asrsea
到底对这个四个参数做了什么呢。
加密过程
其实并没有很复杂的加密流程。
/*
* 下面我用data替代JSON.stringify(bl)
* 简要介绍一下,加密流程
*/
window.asrsea(data, x, y, z) {
const str = randomString(16)
const params = AES.encrypt(AES.encrypt(data, z), str)
const encSecKey = rsa(str)
}
解释一下上面的代码:
randomString()
是用于生成一个随机字符串str
,长度为16。
然后以z
为key
加密原始数据。得到结果后再以str
为key
加密。将此结果作为params
。
然后再通过RSA
加密str
。此结果为encSecKey
。
这里RSA
加密需要的PublicKey
哪里来的呢。其实就是x
, y
。
x
转成整数的值是:65537
。
代码
移至:github
总结
也许你们会问,为什么RSA
加密没有用Nodejs
自带的。嗯,不是我不想,而是网易这个RSA
填充方式似乎没按套路来,也许也是我没用对。所以我,就偷懒直接把他的RSA
加密实现从源码里拿了出来放到了rsa.js
。
如果你用Nodejs
的crypto
实现了,望告知。
还有目前这个没有考虑登录出现验证码的情况。
另外,试了一下Chrome
的debugger
。嗯,很棒。为什么以前不知道用呢。
附
网易实现的rsa
应该是来自这个:RSA in JavaScript