华为商城秒杀时加密验证 device_data 的算法研究

文章讲述了作者尝试通过编程手段破解华为商城Mate60手机抢购时的device_data加密,详细解析了ars_event.js中的加密算法,虽然解出了算法,但因服务器其他验证未破解而未能成功秒杀。

前言

  • 之前华为商城放出 Mate60 手机时, 想给自己和家人抢购一两台,手动刷了好几天无果后,决定尝试编写程序,直接发送 POST 请求来抢。
  • 通过抓包和简单重放发送后,始终不成功。仔细研究,发现 Cookie 中有一个名为 device_data 的数据比较可疑,看起来是加密后的 base64, 很有可能服务器是使用这些值进行了验证。于是决定研究一下,看是否可以破解并用于秒杀。
  • 最后虽然研究出加密算法,并尝试用于秒杀,但由于仍然有其他的限制,暂时放弃,并将相关信息开源。
  • 华为的兄弟姐妹们需要辛苦更改算法了 😃
    在这里插入图片描述

查找 device_data 的生成位置

通过搜索,定位到名为 cp_20230815/…/ars_event.js 的文件,里面有对 ‘device_data’ 赋值的操作,那么加密算法就在这里了。
补充信息: 最新版本的地址已经是 cp_20231215/…/ars_event.js, 但内容没有改变。
在这里插入图片描述

算法分析

初看 ars_event.js , 是进行过混淆的, 简直和天书一样, 而且以前也没怎么用过 js, 不知道怎么下手。不过好在知道 js 的所有源码都在里面, 只要肯花一点时间, 必然是能解析出来的。

于是开始分析, 此处省略一万字。。。

功夫不负有心人,断断续续经过一两周的时间,总算把算法反推出来,并且编写了 java 代码进行验证和 POST 秒杀。虽然事后证明,服务器还有其他验证方式没有破解(比如 IP、UID 验证?),并发10个线程请求, 有4个给我返回非法请求。。。)

算法解释

  • device_data 的数据分两部分:
    • 最前面的 *2k 常量 + 从 479752 中选出的两个数(间隔 3)
    • 要加密的字符串先 base64, 按 4 个字符进行编码
      • 然后在前面加上 8 个随机字符
      • 最后再按 8 个字符为一组的方式编码.

源码

  • 因为源码是从 js 中反推出来的, 主要是为了满足和原有的算法一致, 命名和写法上就比较乱.
/**
 * device_data 的加密/解密 算法
 * https://res.vmallres.com/cp_20230815/js/common/risk/ars_event.js
 * https://res.vmallres.com/cp_20231215/js/common/risk/ars_event.js
 */
@Slf4j
public class ArsEventCrack {
   
   

  //获取华为 function _0x272042 函数中,对字符串加密时采用的位置索引列表
  public LinkedList<Integer> GetEncodeStringIndexArray(int strLength, int blockSize){
   
   
    //最后4字节保持原样
    int charArrayLength = strLength - 4;
    //String[] charArray = strInput.substring(0, strInput.length() - 4).split("");
    LinkedList<LinkedList<Integer>> tmpArray = new LinkedList<>();
    for(int i = 0; i < blockSize; i++){
   
   
      tmpArray.add(new LinkedList<>());
      for(int j = 0; j < charArrayLength; j++){
   
   
        int _tmpVal_1 = j * 2 * (blockSize - 1) + i;
        int _tmpVal_2 = 0;
        if (_tmpVal_1 < charArrayLength){
   
   
          tmpArray.get(i).add(_tmpVal_1);
        }
        if (i != 0) {
   
   
          _tmpVal_2 = j * 2 * (blockSize - 1) - i;
          if (_tmpVal_2 < charArrayLength && _tmpVal_2 > 0) {
   
   
            tmpArray.get(i).add(_tmpVal_2
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值