==请帮忙点点赞,点个关注,谢谢!!==
官网地址:财联社
本文发布的技术与代码仅供技术交流和学习使用,严禁用于数据采集等任何违法活动。请确保合法使用,并独立承担不当使用带来的法律责任。
一、逆向教程
1.我们先来看看请求参数
有个加密参数“sign”,多个翻页结果来对比,似乎是通过last_time来控制的。(让后端知道从什么时候的文章开始返回)
2.解密函数的定位
请出我们的冒号大法。
找了一圈,这个好像挺像,绿框里面的参数在我们的请求负载也有。那确实挺像的,直接上断点。
r是我们请求负载,返回了加密参数,那就是这里了。
3.深入分析
让我们逐层分析
3.1 a()方法分析
先让我们来看看这个方法他返回的是个啥。
这不是我们的请求负载 r 一样的嘛.....再让我们来验证一下直接传r给 p() 方法行不行。
斯.....还是一样,那一样就不管了,直接删a()方法。
3.2 p()方法分析
那还等什么,已经知道p()就是加密方法了。直接进去。
跳转到这里了,直接给上首尾断点
先不着急进去,看看这个函数都干了些啥。
1. 生成了一个t
2. 调用r.sync()方法传入生成的t,结果又赋值给了t
3. 调用o()方法传入生成的t,结果又赋值给了t
4. 返回t
emmm....挺搞人的,那来一部分一部分的看吧。
3.2.1 生成了一个t(上文描述的第一步)
先看看这个t最初生成的是啥。
这是把我们的请求负载给拼接成http get请求参数的格式了
3.2.2 调用r.sync()方法传入生成的t,结果又赋值给了t(上文描述的第二步)
接着来看看r.sync(t)的结果是个啥
生成了一个密文,40位???速想!有什么加密是40位的。(SHA1生成40位加密参数)
来验证一下
对上咯!!确定是SHA1加密了。
3.2.2 调用o()方法传入生成的t,结果又赋值给了t(上文描述的第三步)
接着来看看o(t)的结果是个啥
还是生成了一个密文,32位???速想!有什么加密是32位的。(MD5可生成32位加密参数,这再熟悉不过了吧)
再来验证一下
Congratulations!!!又对上了。
3.2.3 p()方法分析结果总结
p()方法就是将请求负载先拼接成http get请求参数格式的字符串,然后将该字符串进行SHA1加密再进行MD5加密。
二、加密纯算代码
import urllib.parse
import hashlib
import requests
params = {
'app': 'CailianpressWeb',
'id': '1000',
'last_time': '1735251626',
'os': 'web',
'rn': '20',
'sv': '8.4.6',
}
# 对字典的键进行排序,并生成排序后的查询字符串
sorted_data = sorted(params.items(), key=lambda item: item[0]) # 按key排序
query_string = urllib.parse.urlencode(sorted_data) # 转换为URL编码的字符串
# 使用SHA1加密
sha1_hash = hashlib.sha1(query_string.encode('utf-8')).hexdigest()
# 对SHA1加密的结果再进行MD5加密
sign = hashlib.md5(sha1_hash.encode('utf-8')).hexdigest()
# 向请求负载中添加sign
params['sign'] = sign
response = requests.get('请求自己写', params=params)
运行结果: