请求某民日报app数据的时候,发现有个关键参数是securitykey:
比如这一条:

参数如下:

请求数据的时候,securitykey为必填,不填就一定会返回错误。
经过多条数据对比验证,securitykey并非后端即时生成,再返回给前端。无论何时何地请求网页,同一id,securitykey对应也是唯一的。显然,securitykey是前端生成的,而且是主要校验参数。
如果找到securitykey的生成方法?
查找关键字“securitykey”,发现名为“app...”的js 文件里,存在包含securitykey的function:

虽然js文件阅读困难,但还是很容易得知,securitykey是t,而t是上面Object语句生成的:

多次断点,就可以拿到目标securitykey了:

问题的关键,变成t是如何生成的。
生成t的语句,需要的核心参数是两个,e.params, interface_code。interface_code一直是610,可以忽略不计。e.params又是什么?
断点拨到t生成前,打印e.params:

原来核心还是id。
验证一下t是否由Object语句生成:

也没问题。
现在需要找的就是,Object到底是通过哪个function,生成了securitykey。
巧的是,在这条js文件里,搜索“security”,还会标记一条语句:

而且,语句本身也很像加密过程。
可能大功即将告成?
实际上,断点了以后发现没啥用:生成securitykey的时候,根本就不会调用它。
但是, 有个跟t.c结构很像的function,就是上面的t.b。而且Object的参数,是v.b,既然都有.b,那么不如试试。果然,Object使用的"v.b",就是这个"t.b":

这是n的值 :

这当然不是我们需要的securitykey,但是接下来还有一句s(n)需要执行:

s(n)的结果,就是我们需要的值了。
显而易见,所需的securitykey,是对值n加密的结果。而n,是由id拼接固定字符串而成。字符串里,只要更换id数值即可:

最后需要解决的,就是加密方法了。 这里取个巧,看securitykey的结果,怎么看怎么像MD5加密做的,不如试试:
Python里的模拟
import hashlib
def rmrb_s(str):
md= hashlib.md5()
md.update(str.encode(encoding='utf-8'))
return md.hexdigest()
rmrb_id = '6204368'
securitykey = rmrb_s("id=%s|interface_code=610rmj$cd&2e09elp468b7b87dlsye#jipl"%rmrb_id)
print(securitykey)
输出结果如下:

一 毛 一 样 啊!
虽然一半靠运气,但是还是要感动一下,完工!
