JD到家h5版h5st参数算法还原逆向记录

链接:aHR0cHM6Ly9kYW9qaWEuamQuY29tL2h0bWwvaW5kZXgvc3RvcmVIb21lP29yZ0NvZGU9MzA4MDM2JnN0b3JlSWQ9MTE3NjY2NzkmaW1nT3JkZXI9MSZzdG9yZVN0eWxlPW5ldw==

8f6366ee11c14870b85333d86a5d57c5.png

h5st 4.1总共由八段组成

5eda8313d3864bebbd6b705bfb64e3eb.png

29acdb74583c4fe5952fa6c0f474f3a3.png

首先body在这里进行一次加密,这里等价一个sha256

    def sha256_encode(body):
        '''
        :body转化为256:
        :return:
        '''
        # 将参数转换为bytes类型
        data_bytes = bytes(body, 'utf-8')
        # 创建SHA256加密对象
        sha256_obj = hashlib.sha256(data_bytes)
        # 获取SHA256加密结果的十六进制表示
        sha256_hex = sha256_obj.hexdigest()
        return sha256_hex

重点是h5st的生成过程,直接搜索h5st就会发现这里,加密逻辑就在这个平坦流里面,一个一个分析。

07d704d64d65465596f2282b5b296916.png

case0:就是第一段,时间戳的一些格式化处理

f239753f78f14800b95b0be5f6e9553f.png

python还原:

        t = int(datetime.now().timestamp() * 1000)
        timestamp = t / 1000.0  # 将时间戳除以1000,转换为秒
        dt = datetime.fromtimestamp(timestamp)
        st1 = dt.strftime('%Y%m%d%H%M%S%f')[:-3]  # 格式化日期字符串,去掉最后三位微秒数
        print(st1)

case1:去this里面获取tk, signId,fp等参数

ce60f5dec24341a1b91cd1187a9ef481.png

case2:对case0生成的时间加盐处理,这个后面会用到

b6c5d7a3bdad43fda11ca9e4ad6a26b9.png

case3: 对参数进行一次sha512加密,

4e0053f144674d1692844f46fed78e2f.png

bf5dc3dc38e64cb6a72ba5822fe1fb42.png

    def sha512_code(tk, fp, ts, ai):
        '''
        :param fp:
        :param ts:
        :param ai:
        :return:
        '''
        rd = 'Jx3v0PoORt7z'
        str_to_hash = ''.join([tk, fp, ts, ai, rd])
        hashed = hmac.new(bytes(tk, 'utf-8'), bytes(str_to_hash, 'utf-8'), digestmod=hashlib.sha512).hexdigest()
        return hashed

case5: case5里面的case2生成的y就是h5st,查看下参数

e71849db68bf4eed893d73fbe7e10090.png

m和e好像都还没见过,看一下m的来历

4776ddc8004c44218024ee8126d5f71c.png

貌似是由body和上面case3生成的sha512加密传参做的一次处理

b1c0f510c70b4adbb1c00db4661e9ca4.png

进入这个函数看一下,原来就是个MD5

752e5cc5ba914928800eee5d73c1c688.png

    def md5_code(body, sha512_result, t):
        '''
        512 + body再MD5
        :param data:
        :param key:
        :return:
        '''
        param = {
            "appid": "JDReactDaoJiaH5",
            "functionId": "dj_storeIndexSearch_searchByCategory",
            "client": "H5",
            "clientVersion": "8.39.0",
            "body": body
        }
        sorted_data = {k: param[k] for k in sorted(param)}
        sParam = '&'.join(['{}:{}'.format(key, value) for key, value in sorted_data.items()])
        sParam = sParam + f'&t:{t}'
        sParam = f"{sha512_result}{sParam}{sha512_result}"
        m2 = hashlib.md5()
        m2.update(sParam.encode("utf8"))
        sign = m2.hexdigest()
        return sign

接下来看e的来历,查看堆栈回推一下,o是从t里面来的

6d21bc2b96ac492ead2684275fff3496.png

最后发现加密逻辑是在case6里面,this[a(397, 0, 386)]();进入这个函数,是一个aes-cbc加密

b9443d46b256454eb4356a03caed3f38.png

    def encrypt_pkcs7_to_java():
        '''
        :return:
        '''
        env = {
            "sua": "Linux; Android 6.0; Nexus 5 Build/MRA58N",
            "pp": {
                "p1": "rpsawxebe"
            },
            "random": "P9WjhLQ1Z7",
            "referer": "https://plogin.m.jd.com/",
            "v": "v0.1.6",
            "fp": "lfmt63g5in9345q7"
        }
        data = json.dumps(env, indent=2)
        key = 'HL4|FW#Chc3#q?0)'.encode('utf-8')
        iv = '0102030405060708'.encode('utf-8')
        cipher = AES.new(key, AES.MODE_CBC, iv)
        padded_data = pad(data.encode('utf-8'), AES.block_size, style='pkcs7')
        ciphertext = cipher.encrypt(padded_data)
        return binascii.hexlify(ciphertext).decode('utf-8')

关键参数都看完了,最后拼接一下就可以。。。。

纯python还原,具体的就不写了,把上面代码组合一下就可以

4cb1fe0e370c4950965635b17190aa28.png

73cd7df99abd4e9faf931371039362bb.png

 

 

 

  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值