分析网易云音乐API加密时的问题

在分析网易云音乐API加密的时候,参考了网上很多博客,大致了解了流程,同时也用这些方法成功的拿到了好几个API的数据。

但是,在尝试获取用户的听歌排行时,却发生了问题,后台没有返回数据。第一想到的是,我是不是API调用错了,刷新了几次,排除了这个问题。第二,是不是这个API传的数据格式错了,查看Sources,找到这行代码,多猜测,多打印数据可以猜出来 JSON.stringify(i9b) 就是要传给后台的,即将加密的参数。

有人可能要问了,你怎么知道是这段代码进行的参数加密,原因很简单,通过network。record?这个是我们请求的api,这是用post进行请求的,可以看到form表单里面提交了两个数据,一个是params,另外一个是encSecKey,那么我们可以通过搜索这两个关键字,params比较大众,我们搜encSecKey这个关键字好了。

可以看到浏览器是请求了很多文件的

那么我们搜索哪一个文件?通过network,我们可以知道发起请求的是哪个文件

点进去,搜索即可。

好像有一点偏题了...我们继续讲。通过控制台打印这个字段,多次确认后,没有传错数据格式,排除此可能。

第三,是否是因为这个API接口的参数换了一种加密方式,导致我算出来的参数是错的?不应该吧,不同的接口用不同的加密方式,网易不累么。。。再次逐语句后,执行过程和之前的接口是一致的,加密的参数也一样,也排除了这种可能。这些就比较疑惑了,去网上搜索,发现有的Request请求必须要加上特定的Headers,恍然大悟。查看了下network,把所有headers全部添加到了postman里面,激动地点击send。返回200。没有数据。感到绝望。为什么?还能有什么原因?我遗漏了什么?浏览器里的请求和我在postman里的请求肯定是有某些地方不一样!它躲在了哪里?

一夜无话。

第二天,搜索postman的一些调试技巧,发现了直接从浏览器抓取request的方法,看到这个方法,很开心,这样就不需要我手动输入参数了,因为自己可能会输漏了什么。抓取的浏览器的request后,开始看看他的请求了。

8个请求头,两个表单参数,没什么特殊的啊。那么开始更换表单里的参数,替换成我自己的参数后,拿不到数据了。加密得到的参数错误了?网易云音乐的加密一共是进行了两次AES加密,一次RSA加密。第一次AES加密的key是固定的,第二次加密的key是随机的16位数,然后对随机的这个key进行一次RSA加密,结果也就是我们的encSecKey。

为了验证是否是加密错误,继续在浏览器中进行调试,拿到它随机的16位数之后,用自己的加密方法进行计算,果然,第二次AES加密后,不是正确的结果了。问题找到了,自己的加密算法出现了错误。但,为什么前几次API都能成功调用?继续查看第一次加密时的结果,和浏览器里的正确结果对比一下,是一致的,那么错误发生在,第二次加密身上。

手动将第一次的结果,放在加密函数的参数里,惊奇的发现pyCharm有一个警告

一行语句超过了120个字符,虽然不知道为什么有个120字符的要求,但问题肯定就出在这了,我所要加密的字符太长了。这下豁然开朗,之前几个API能成功,是因为,第一次加密返回的结果长度不是很长。因为他们的数据不是很长,前两个API的数据格式如下

{"ids":"[440208476]","br":128000,"csrf_token":""}
{"userId":"317556268","offset":"0","total":"true","limit":"20","csrf_token":""}

而这个API的数据格式是这样的

{"uid":"285056784","type":"-1","limit":"1000","offset":"0","total":"true" ,"csrf_token":""}

的确是长了很多。我的解决办法是删了无用的 "csrf_token":"" ,减少了一点长度,重新加密传给后台后,成功拿到数据。

当然这是治标不治本的方法。