逆向爬虫35 常见加密的python实现
逆向爬虫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作为之后手机请求服务器的凭证
思路:
- 直接用固定uuid是否可行?
- 动态生成是否可行?
- 过程模拟,模拟获取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的的明文
读取请求头/请求体/url 数据,某个字段
读取数据拼接字符串
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实现相关推荐
- 【Python网络爬虫】爬虫常见加密解密算法
](https://img2020.cnblogs.com/blog/2501174/202108/2501174-20210816091906408-1932195692.png) 简介# 本文总结 ...
- python爬虫之逆向破解_js逆向爬虫实战(2)--新快之加密参数破解
爬虫js逆向系列 我会把做爬虫过程中,遇到的所有js逆向的问题分类展示出来,以现象,解决思路,以及代码实现.我觉得做技术分享,不仅仅是要记录问题,解决办法,更重要的是要提供解决问题的思路.怎么突破的, ...
- 史上最全总结!爬虫常见加密解密算法
文章目录 简介 JavaScript 加密解密模块 Crypto-JS Node-RSA JSEncrypt Python 加密解密库 Cryptodome & Crypto Hashlib ...
- python常见加密方式总结踩坑小贴士
本文是向大家介绍python中常见的一些加密方式,在使用python的时候遇到数据加密的情况时,可以根据实际场景来选择加密的方式对数据进行加密,加强数据传输的安全性. 一.前言 日常工作中经常会看到各 ...
- Python与常见加密方式
Python与常见加密方式 前言 数据加密与解密通常是为了保证数据在传输过程中的安全性,自古以来就一直存在,古代主要应用在战争领域,战争中会有很多情报信息要传递,这些重要的信息都会经过加密,在发送到对 ...
- [python爬虫] Selenium常见元素定位方法和操作的学习介绍(转载)
转载地址:[python爬虫] Selenium常见元素定位方法和操作的学习介绍 一. 定位元素方法 官网地址:http://selenium-python.readthedocs.org/locat ...
- Python爬虫编程常见问题解决方法
Python爬虫编程常见问题解决方法 参考文章: (1)Python爬虫编程常见问题解决方法 (2)https://www.cnblogs.com/xpwi/p/9604015.html (3)htt ...
- Python爬虫之js加密破解,抓取网易云音乐评论生成词云
js破解历程 前言 技能点 界面概况 静态网页动态网页 页面解析 step1: 找参数step2:分析js函数step3:分析参数step4: 校验step5:转为python代码 编写爬虫 很多人学 ...
- Python爬虫总结——常见的报错、问题及解决方案
Python爬虫基础--HTML.CSS.JavaScript.JQuery网页前端技术 Python爬虫基础--正则表达式 Python爬虫基础--re模块的提取.匹配和替换 Python爬虫基础- ...
最新文章
- java getoptionvalue_How to get option value in database
- 安装iis,php,mysql总结
- 2018年11月份GitHub上最热门的开源项目
- RepositionBars的用法和参数分析
- 深度学习与计算机视觉(四)反向传播及其直观理解
- 相亲对象能有多油腻......
- Redis主从复制原理学习
- android8 通知呼吸灯_Android8.0及以上的Notification
- 揭秘支撑双 11 买买买背后的硬核黑科技!
- 基于Boost无锁队列实现的内存池
- pytorch---模型加载与保存(6)通过设备保存/加载模型
- font: 12px/1.5 Tahoma, Helvetica, Arial, sans-serif;
- nginx access日志log_format优化之request_time 和upstream_response_time差别
- 手把手教您怎么编写第一个单片机程序
- 我的日常工作剖析,美好的一天,从每一天开始。
- 计算机和网络之间有个感叹号,网络有个感叹号!电脑无线网络连接不上的几种常见问题...
- golang通过onvif协议控制云台
- 无线耳机哪个品牌音质好?2023无线蓝牙耳机音质排行
- Spring Boot框架
- Wechaty创建属于自己的微信机器人(附源码)
热门文章
- 直播课报名 | 2022 看云计算如何赋能跨境电商企业再增长
- 微信小程序之回调函数中用setData
- 一款以Python编码的自动化大规模漏洞测试工具
- jmeter插件管理器
- 网页设计师要懂的前端知识之HTML标签及规范
- EQG-RACE: Examination-Type Question Generation翻译
- STM32 USB无法连接电脑
- 内网渗透之MSF框架模块详细作用介绍
- 计算机等级考试网络工程师好考吗,计算机等级考试一次通过,原来是看了计算机四级网络工程师考试内容...
- echarts 如何在地图组件上加入南海