这篇文章是之前在公众号写的
登录https://music.163.com/ 网易云音乐搜索新说唱,打开Chrome的开发工具工具选择Network并重新加载页面,找到与评论数据相关的请求即name为
web?csrf_token=的POST请求,如下图所示
查看该请求的headers我们发现formData包含了两个参数:params、encSecKey。显然这两个参数是经过js加密的,这就是网易云反爬虫的一种策略。如下图:
我们再来看一下请求的Initiator有个core 2ab1b2b…js。因此我们需要分析一下这个js,找出formData加密的规则即可。
将js文件进行格式化,全局搜索params或者encSecKey
params和encSecKey是从bSC8u这个对象中取的
k8c.cE9v({
params: bSC8u.encText,
encSecKey: bSC8u.encSecKey
})
而这个对象是由windows.asrsea() 这个方法获得的,定位到该方法。如下图所示:
通过分析代码我们发现 d函数才是最终的出口。分析d函数:
1、通过 a(16) 函数生成一个长度为16的随机字符串
2、encText这个参数通过两次调用 b(a,b) 函数完成,这个函数的作用为AES加密
3、调用 c(i, e, f)得到encSecKey,这个函数的作用是进行RSA加密
AES加密
AES(Advanced Encryption Standard)对称加密算法是一种高级数据加密标准,是美国联邦政府采用的一种区块加密标准,可有效抵制针对DES的攻击算法。特点:密钥建立时间短、灵敏性好、内存需求低、安全性高。
RSA加密
RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。到目前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
通过上面分析,除了 i 是一个随机字符串,我们只需要知道d、e、f、g这四个参数就可以构造请求进行后续操作了。接下来我们进行js断点调试。
首先我们先实现函数a,即生成16位的随机字符
#生成随机长度为16的字符串的二进制编码
def random_b():
seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
sa = []
for i in range(16):
sa.append(random.choice(seed))
salt = ''.join(sa)
return bytes(salt, 'utf-8')
# 更简单的做法
# return bytes(''.join(random.sample('1234567890DeepDarkFantasy', 16)), 'utf-8')
其次来实现加密参数的生成(说白了就是翻译js代为为python代码)
#第二参数,rsa公匙组成
pub_key = "010001"
#第三参数,rsa公匙组成
modulus = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
#第四参数,aes密匙
secret_key = b'0CoJUm6Qyw8W8jud'
"""
AES 加密
"""
def aes_encrypt(text