逆向爬虫35 常见加密的python实现

目的:将App逆向中常见的算法用python实现,方便以后的使用

Java常见加密

隐藏字符串

  • 字符串是以字节编码数组的形式存储或网络传输的,因此可以通过指定编码的字节数组来代替字符串,起到隐藏字符串的目的。
  • Java中的字节是有符号数,范围是-128 ~ 127,python中的字节是无符号数,范围是0 ~ 255,因此想要把java中的字节数组写到python中,需要进行转化
  • 下面是在java中将字符串转化为字节数组的示例,可以看到java中的字节有正有负
import java.util.Arrays;public class Hello {public static void main(String[] args) {String s1 = new String("一个小黑666");byte[] b1 = s1.getBytes();System.out.println(Arrays.toString(b1)); //[-28, -72, -128, -28, -72, -86, -27, -80, -113, -23, -69, -111, 54, 54, 54]}
}
  • 下面是在python中将字符串转化为字节数组的示例,可以看到python中的字节只有正,没有负
s1 = "一个小黑666"
byte_s1 = s1.encode()
list_s1 = [b for b in byte_s1]
print(list_s1)  # [228, 184, 128, 228, 184, 170, 229, 176, 143, 233, 187, 145, 54, 54, 54]
  • 下面是将java中的字节数组转换成python字节数组的代码
# 从java中得到的字节数组
byte_s1 = [-28, -72, -128, -28, -72, -86, -27, -80, -113, -23, -69, -111, 54, 54, 54]
byte_b2 = bytearray()  # 利用bytearray构造空的python字节数组
for b in byte_s1:b = b & 0xffbyte_b2.append(b)
s2 = byte_b2.decode()
print(s2)   # 一个小黑666

注意事项

  • 使用的编码是 utf-8 还是 gbk
  • 一般用于加密哈希算法中的盐和对称加密AES的key和iv

uuid

  • uuid是一个随机id字符串,每一种语言中都会内置生成uuid的方法。
  • Java中生成uuid的方法
import java.util.UUID;public class Hello {public static void main(String[] args) {String uuid = UUID.randomUUID().toString();System.out.println(uuid);   // ebcc80c4-7941-4c5f-9c86-47ace1f695f5}
}
  • Python中生成uuid的方法
import uuiduid = str(uuid.uuid4())
print(uid)  # 8dd4aeb0-7a93-4fec-8c49-662af2ccfa77
  • uuid分为两种情况:

  • 第一种,每次请求,抓包都不一样 ——> 直接伪造生成

  • 第二种,抓包发现uuid固定,但app清除数据或重新卸载安装时,uuid发生变化

    ​ 这种情况的uuid可能是通过发送固定请求到服务求,由服务器返回的uuid,保存在App本地的xxx.xml文件中,该uuid作为之后手机请求服务器的凭证

  • 思路:

    1. 直接用固定uuid是否可行?
    2. 动态生成是否可行?
    3. 过程模拟,模拟获取uuid的请求获取uuid,带上服务器返回的uuid发送请求。

十六进制随机值

  • Java生成十六进制随机值的代码
import java.math.BigInteger;
import java.security.SecureRandom;public class Hello {public static void main(String[] args) {// 随机生成80为0或1,10个字节BigInteger v1 = new BigInteger(80, new SecureRandom());// 让字节以16进制展示String res = v1.toString(16);System.out.println(res);    // 6a4c6fdfb797d5450c54}
}
  • Python生成十六进制随机值的代码
import randomdata = random.randbytes(10)    # randombytes只在python3.9以后才有
randHex = "".join(['%02x' %(byte) for byte in data])
print(randHex)  # 3d4814c40e44a196df1c
  • 如果python不是3.9可以用以下版本
import randombyte_list = []
for i in range(10):byte_list.append(random.randint(0, 255))
res = "".join(["%02x" %(b) for b in byte_list])
print(res)  # 08e4461bf11a8631960c

时间戳

  • Java中生成时间戳的代码
public class Hello {public static void main(String[] args) {String t1 = String.valueOf(System.currentTimeMillis() / 1000);String t2 = String.valueOf(System.currentTimeMillis());System.out.println(t1);     // 1652538360System.out.println(t2);     // 1652538360408}
}
  • Python中生成时间戳的代码
import timet1 = str(int(time.time()))
t2 = str(int(time.time()*1000))
print(t1)   # 1652538447
print(t2)   # 1652538447351

注意事项

  • 时间戳在请求头的参数里是以字符串形式出现的

  • 时间戳的意义:

    ​ 1.大厂会校验请求携带的时间戳

    ​ 2.时间戳会当作明文的一部分放进哈希算法进行加密,再根据哈希加密进行校验

md5 (其它哈希用法和md5类似)

  • Java中的md5代码 (含加盐)
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;public class Hello {public static void main(String[] args) throws NoSuchAlgorithmException {String name = "一个小黑";MessageDigest instance = MessageDigest.getInstance("MD5");instance.update("salt".getBytes());     // 加盐byte[] nameBytes = instance.digest(name.getBytes());System.out.println(Arrays.toString(nameBytes)); // [32, 104, -25, 107, 106, -6, 40, 68, -127, 84, 99, -121, 7, 93, 8, -23]// 十六进制展示StringBuilder sb = new StringBuilder();for (int i = 0; i < nameBytes.length; i++) {int val = nameBytes[i] & 255;if (val < 16) {sb.append("0");}sb.append(Integer.toHexString(val));}String hexData = sb.toString();System.out.println(hexData);    // 2068e76b6afa284481546387075d08e9}
}
  • Python中的md5代码 (含加盐)
import hashlibm = hashlib.md5()
m.update("salt".encode("utf-8"))    # 加盐
m.update("一个小黑".encode("utf-8"))v1 = m.digest()
v2 = m.hexdigest()
print(v1)   # b' h\xe7kj\xfa(D\x81Tc\x87\x07]\x08\xe9'
print(v2)   # 2068e76b6afa284481546387075d08e9

注意事项

  • md5密文的特点是32位16进制数字

  • 获得密文后可能会进一步变大小写

  • 有盐的话需要找盐,最重要的是要找到md5的的明文

    1. 读取请求头/请求体/url 数据,某个字段

    2. 读取数据拼接字符串

      ​ name=apphao&age=18&size=20

      ​ nameapphaoage18size20

      ​ 固定值namewupeiqiage19size20固定值

  • 可能会拿到密文后,获取里面的固定几位,再添加到后面,导致密文超过32位

  • md5后期可以利用hook技术定位

AES

  • Java中的AES代码
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;public class Hello {public static void main(String[] args) throws Exception {String data = "一个小黑";String key = "fd6b639dbcff0c2a1b03b389ec763c4b";String iv = "77b07a672d57d64c";// 加密byte[] raw = key.getBytes();SecretKeySpec sKeySpec = new SecretKeySpec(raw, "AES");IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, ivSpec);byte[] encrypted = cipher.doFinal(data.getBytes());System.out.println(Arrays.toString(encrypted)); // [-91, -126, 100, 73, -87, -97, -41, 24, -125, -49, 2, 112, 22, 22, -63, 69]}
}
  • Python中的AES代码
# pip install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import padKEY = "fd6b639dbcff0c2a1b03b389ec763c4b"
IV = "77b07a672d57d64c"def aes_encrypt(data_string):aes = AES.new(key=KEY.encode("utf-8"),mode=AES.MODE_CBC,iv=IV.encode("utf-8"))raw = pad(data_string.encode("utf-8"), 16)return aes.encrypt(raw)data = aes_encrypt("一个小黑")
print(data) # b'\xa5\x82dI\xa9\x9f\xd7\x18\x83\xcf\x02p\x16\x16\xc1E'
print([i for i in data])    # [165, 130, 100, 73, 169, 159, 215, 24, 131, 207, 2, 112, 22, 22, 193, 69]

注意事项

  • 遇到AES找key,找iv
  • 又时还会对加密后的密文进行base64编码

gzip压缩

  • Java中的gzip代码
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;public class Hello {public static void main(String[] args) throws IOException {// 压缩String data = "一个小黑";// System.out.println(Arrays.toString(data.getBytes()));ByteArrayOutputStream v0_1 = new ByteArrayOutputStream();GZIPOutputStream v1 = new GZIPOutputStream((v0_1));v1.write(data.getBytes());v1.close();byte[] arg6 = v0_1.toByteArray();  //gzip压缩后:arg6System.out.println(Arrays.toString(arg6));    // [31, -117, 8, 0, 0, 0, 0, 0, 0, -1, 123, -78, -93, -31, -55, -114, 85, 79, 55, -12, -65, -36, 61, 17, 0, 44, -30, 103, 119, 12, 0, 0, 0]// 解压缩ByteArrayOutputStream out = new ByteArrayOutputStream();ByteArrayInputStream in = new ByteArrayInputStream(arg6);GZIPInputStream ungzip = new GZIPInputStream(in);byte[] buffer = new byte[256];int n;while ((n = ungzip.read(buffer)) >= 0) {out.write(buffer, 0, n);}// byte[] res = out.toByteArray();// System.out.println(Arrays.toString(res));System.out.println(out.toString("UTF-8"));    // 一个小黑}
}
  • Python中的gzip代码
import gzips_in = "一个小黑".encode('utf-8')
s_out = gzip.compress(s_in)
print([i for i in s_out])   # [31, 139, 8, 0, 230, 159, 128, 98, 2, 255, 123, 178, 163, 225, 201, 142, 85, 79, 55, 244, 191, 220, 61, 17, 0, 44, 226, 103, 119, 12, 0, 0, 0]res = gzip.decompress(s_out)
# print(res)
print(res.decode('utf-8'))  # 一个小黑

注意事项

  • gzip压缩一般用于设备指纹信息压缩
  • java和python的gzip压缩出来的结果,个别字节不一样,需要特殊处理

base64

  • Java中的base64代码
import java.util.Base64;public class Hello {public static void main(String[] args) {String name = "一个小黑";// 加密Base64.Encoder encoder  = Base64.getEncoder();String res = encoder.encodeToString(name.getBytes());System.out.println(res); // 5LiA5Liq5bCP6buR// 解密Base64.Decoder decoder  = Base64.getDecoder();byte[] origin = decoder.decode(res);String data = new String(origin);System.out.println(data); // 一个小黑}
}
  • Python中的base64代码
import base64name = "一个小黑"res = base64.b64encode(name.encode('utf-8'))
print(res) # b'5LiA5Liq5bCP6buR'data = base64.b64decode(res)
origin = data.decode('utf-8')
print(origin) # 一个小黑

逆向爬虫35 常见加密的python实现相关推荐

  1. 【Python网络爬虫】爬虫常见加密解密算法

    ](https://img2020.cnblogs.com/blog/2501174/202108/2501174-20210816091906408-1932195692.png) 简介# 本文总结 ...

  2. python爬虫之逆向破解_js逆向爬虫实战(2)--新快之加密参数破解

    爬虫js逆向系列 我会把做爬虫过程中,遇到的所有js逆向的问题分类展示出来,以现象,解决思路,以及代码实现.我觉得做技术分享,不仅仅是要记录问题,解决办法,更重要的是要提供解决问题的思路.怎么突破的, ...

  3. 史上最全总结!爬虫常见加密解密算法

    文章目录 简介 JavaScript 加密解密模块 Crypto-JS Node-RSA JSEncrypt Python 加密解密库 Cryptodome & Crypto Hashlib ...

  4. python常见加密方式总结踩坑小贴士

    本文是向大家介绍python中常见的一些加密方式,在使用python的时候遇到数据加密的情况时,可以根据实际场景来选择加密的方式对数据进行加密,加强数据传输的安全性. 一.前言 日常工作中经常会看到各 ...

  5. Python与常见加密方式

    Python与常见加密方式 前言 数据加密与解密通常是为了保证数据在传输过程中的安全性,自古以来就一直存在,古代主要应用在战争领域,战争中会有很多情报信息要传递,这些重要的信息都会经过加密,在发送到对 ...

  6. [python爬虫] Selenium常见元素定位方法和操作的学习介绍(转载)

    转载地址:[python爬虫] Selenium常见元素定位方法和操作的学习介绍 一. 定位元素方法 官网地址:http://selenium-python.readthedocs.org/locat ...

  7. Python爬虫编程常见问题解决方法

    Python爬虫编程常见问题解决方法 参考文章: (1)Python爬虫编程常见问题解决方法 (2)https://www.cnblogs.com/xpwi/p/9604015.html (3)htt ...

  8. Python爬虫之js加密破解,抓取网易云音乐评论生成词云

    js破解历程 前言 技能点 界面概况 静态网页动态网页 页面解析 step1: 找参数step2:分析js函数step3:分析参数step4: 校验step5:转为python代码 编写爬虫 很多人学 ...

  9. Python爬虫总结——常见的报错、问题及解决方案

    Python爬虫基础--HTML.CSS.JavaScript.JQuery网页前端技术 Python爬虫基础--正则表达式 Python爬虫基础--re模块的提取.匹配和替换 Python爬虫基础- ...

最新文章

  1. java getoptionvalue_How to get option value in database
  2. 安装iis,php,mysql总结
  3. 2018年11月份GitHub上最热门的开源项目
  4. RepositionBars的用法和参数分析
  5. 深度学习与计算机视觉(四)反向传播及其直观理解
  6. 相亲对象能有多油腻......
  7. Redis主从复制原理学习
  8. android8 通知呼吸灯_Android8.0及以上的Notification
  9. 揭秘支撑双 11 买买买背后的硬核黑科技!
  10. 基于Boost无锁队列实现的内存池
  11. pytorch---模型加载与保存(6)通过设备保存/加载模型
  12. font: 12px/1.5 Tahoma, Helvetica, Arial, sans-serif;
  13. nginx access日志log_format优化之request_time 和upstream_response_time差别
  14. 手把手教您怎么编写第一个单片机程序
  15. 我的日常工作剖析,美好的一天,从每一天开始。
  16. 计算机和网络之间有个感叹号,网络有个感叹号!电脑无线网络连接不上的几种常见问题...
  17. golang通过onvif协议控制云台
  18. 无线耳机哪个品牌音质好?2023无线蓝牙耳机音质排行
  19. Spring Boot框架
  20. Wechaty创建属于自己的微信机器人(附源码)

热门文章

  1. 直播课报名 | 2022 看云计算如何赋能跨境电商企业再增长
  2. 微信小程序之回调函数中用setData
  3. 一款以Python编码的自动化大规模漏洞测试工具
  4. jmeter插件管理器
  5. 网页设计师要懂的前端知识之HTML标签及规范
  6. EQG-RACE: Examination-Type Question Generation翻译
  7. STM32 USB无法连接电脑
  8. 内网渗透之MSF框架模块详细作用介绍
  9. 计算机等级考试网络工程师好考吗,计算机等级考试一次通过,原来是看了计算机四级网络工程师考试内容...
  10. echarts 如何在地图组件上加入南海