网易云音乐Ajax Post参数加密方法

网易云音乐Ajax Post参数加密方法

首先进入网易云音乐首页,并且打开chrome开发者工具。在搜索栏输入文字。

点开chrome开发者工具中的network,选中XHR,可以看到javascript刚刚发起的ajax请求。

在initiator中可以看到ajax发起方在core.js中具体的某一行。

点开某个请求,可以看到请求头,以及返回的json字符串。

点击initiator中具体的行数。会跳转到具体的代码,即整个core.js源代码。

将其下载下来,用代码查看工具打开,如下采用的是visual studio code。

Fiddler

利用Fiddler写入规则。Fiddler会将刚刚下载下来的本地core.js代替服务器的core.js进行调试。在chrome开发者工具network中需要勾选disabled cache,以防止浏览器利用缓存。

Fiddler中写入规则时,有Test选项,可以进行测试,以检查规则写入是否正确。

发现ajax请求为post请求,form表单参数为params和encSecKey。但表单参数都进行了加密处理。

虽然整个js进行了压缩混淆处理,但请求参数字符串一定没有变,用visual studio code的搜索功能,可以找到enSecKey的位置。分别如下所示:

其主要的加密过程就是a,b,c,d,e函数。

在上述的所在区域中可以利用window.console.warn或者console.log输出注入参数值。例如:

查找bsl3x,可以发现[“流泪”,”强”]等数组中的key将按如下的字典转换为后面的16进制编码:

红线加入的j0x即为请求明文,在chrome中的console中可以看到输出:

输出的s即为明文请求,可以看出是一个json.

为了进一步查看整个加密过程,可以继续查找,以及利用搜索引擎,发现加密主要用了Crypto.js这个加密库,以及OHDove这个rsa加密库(该库诞生于1998年,支持的padding方法有限)。

为了分析Crypto.js加密的过程,可以写一个测试文件进行调试。

先npm install Crypto安装Crypto。OHDove的库需要自行下载。

加密主要是d函数,d中先调用a过程生成16位的随机字符串。然后调用一次b过程进行加密(除明文外,密钥固定),再调用一次b过程(明文为上次加密结果,密钥为a过程生成的16位随机字符串)对上一次的加密结果再进行一次加密。encSecKey则是调用c过程(对a过程生成的16位随机字符串进行加密,其他参数均固定)。

首先分析b函数。

我们可以写一个测试文件来进行测试:

先调试CryptoJS.enc.Utf8.parse(),发现它先进行URI编码,又使用了unescape解码(该方法在最新的Javascript中已经不建议使用),可以认为String经过编码,解码后没有变化。

之后跳转latin1Str,将字符串转换为数组(每4个字符串进行一组编码)。

具体的加密过程(AES加密的详细说明可以看blog.csdn.net/qq_282051

通过下面的注释可以看出该方法采用的是PKCS7补位。

因此可以用python进行模拟。

Python代码:

测试结果

之后分析OHDove的RSA库(RSA算法过程:blog.csdn.net/clj198606)。

网易云音乐的加密公钥是16进制编码的,可以直接转换成16进制数。

OHDove有一份注释详尽的源代码。通过阅读源代码,可以看出其支持三种padding方式:

① 明文在拆分成块时,后面不足的全部补0。(该方法如果不转换成二进制块,相当于放大了原明文转换的16进制整数,直接用书本方法进行加密运算,速度更慢。而且补0的个数未知,需要计算)

② 明文在拆分成块时,明文先进行倒序,然后在前面补0,相当于①方法倒过来。(该方法实现起来简单,可以直接将明文转换成16进制大整数m,由于在前面补0,并不增加大整数的大小。以及将publickey和module字符串转换成16进制整数,利用书本中的基本加密公式:m^publickey mod module直接得到加密后的整数,最后将加密后的整数再进行16进制编码,即可得到密文。由于没有采用二进制分块运算,计算速度不快)

③ 采用PKCS1_5的pad方法。(该方法如果不采用二进制块运算,实现起来困难。采用PyCrypto库,利用construct方法生成rsa对象,利用PyCrpto自带的PKCS1_5 RSA方法加密,发送给服务器时,无法得到返回结果。服务器可能无法对其进行RSA解密。由于PyCrypto为了计算速度,其中加密具体过程是已经进行了编译的pyx文件,无法直接分析过程。所以该方法难以使用。)

最后总结,用python的requests库来进行测试。

调试窗口:

控制台输出

具体代码见:github.com/leo0309/wang

发布于 2018-02-28