day07-java常见加密
1.Java常见加密
1.1 隐藏字节
TreeMap map = new TreeMap();
map.put("sign",x);
# 搜索关键字 sign
String a = new String(new byte[]{-26, -83, -90, -26, -78, -101, -23, -67, -112});
TreeMap map = new TreeMap();
map.put(a,x);
# hook机制,找到TreeMap中的put方法,替换成我自己的某个方法。
function newPut(key,value){
console.log(key,value); 再去获取调用栈。
}
String salt = "xxssasdfasdfadsf";
String v4 = new String(new byte[]{-26, -83, -90, -26, -78, -101, -23, -67, -112});
-
示例1:
String v1 = new String(new byte[]{26, 83, 90, 26, 78, 101, 23, 67, 112});
# 字节列表 byte_list = [26, 83, 90, 26, 78, 101, 23, 67, 112] # 字节列表 -> python的字节数组 bs = bytearray() for item in byte_list: bs.append(item) # python的字节数组 -> 编码 -> 字符串 str_data = bs.decode('utf-8') print(str_data)
-
示例2:
String v4 = new String(new byte[]{-26, -83, -90, -26, -78, -101, -23, -67, -112}); # java字节:有符号 -128 ~ 127 # python:无符号 0 ~ 255
byte_list = [-26, -83, -90, -26, -78, -101, -23, -67, -112] bs = bytearray() # python字节数组 for item in byte_list: if item < 0: item = item + 256 bs.append(item) str_data = bs.decode('utf-8') # data = bytes(bs) print(str_data)
注意事项:什么编码?(utf-8)
String v4 = new String(new byte[]{-26, -83, -90, -26, -78, -101, -23, -67, -112});
# 类似于Java中的字节数组
data = "张三懵逼了"
data_bytes = data.encode('utf-8')
data_list = bytearray()
for item in data_bytes:
data_list.append(item)
res = data_list.decode('utf-8')
print(res)
提醒:MD5加密盐、AES加密key、iv;
1.2 uuid
抖音udid
import java.util.UUID;
public class Hello {
public static void main(String[] args){
String uid = UUID.randomUUID().toString();
System.out.println(uid);
}
}
import uuid
uid = str(uuid.uuid4())
print(uid)
29cd5f50-4b4c-457b-9a59-33a12e3edd10
1.第一类使用uuid
抓包发现,每次请求值不一样:d7cb3695-5105-4aaa-b0a8-8188e0977143
2.第一次运行生成UUID
- 刚开始运行:调用uuid算法生成一个值。
- 写入XML文件
- 再使用
- 优先去XML文件中找
- uuid算法
此时测试:
- 清除app数据
- 必须卸载app,重新安装
1.3 随机值
抖音:openudid
import java.math.BigInteger;
import java.security.SecureRandom;
public class Hello {
public static void main(String[] args) {
// 随机生成80位,10个字节
BigInteger v4 = new BigInteger(80, new SecureRandom());
// 让字节以16进制展示
String res = v4.toString(16);
System.out.println(res);
}
}
import random
data = random.randbytes(10) # pytho3.9
ele_list = []
for item in data:
# 184 十进制 -> 十六进制
# hex(item) #
ele = hex(item)[2:]
res = "".join(ele_list)
print(res)
data = "".join([ hex(item)[2:] for item in random.randbytes(10)])
import random
data = random.randbytes(10) # pytho3.9
# b' I\xbf\xf0#\x15}q\x83Q'
print([item for item in data])
print([hex(item)[2:] for item in data])
print([hex(item)[2:].rjust(2, "0") for item in data])
# print("".join([hex(item)[2:] for item in data]))
print("".join([hex(item)[2:].rjust(2, "0") for item in data]))
# 3.9以前
import random
byte_list = [random.randint(0, 255) for i in range(10)]
# b' I\xbf\xf0#\x15}q\x83Q'
print([item for item in byte_list])
print([hex(item)[2:] for item in byte_list])
print([hex(item)[2:].rjust(2, "0") for item in byte_list])
# print("".join([hex(item)[2:] for item in data]))
print("".join([hex(item)[2:].rjust(2, "0") for item in byte_list]))
小补充:十六进制
import random
data = random.randbytes(10) # pytho3.9
ele_list = []
for item in data:
ele = hex(item)[2:].rjust(2,"0")
res = "".join(ele_list)
print(res)
data = "".join([ hex(item)[2:].rjust(2,"0") for item in random.randbytes(10)])
转换十六进制字符串:
-
内置函数
v1 = hex(199) '0xc7'
-
字符串格式化
v2 = "%x" %(199,) 'c7'
v3 = "%02x" %(5,) '05'
import random
byte_list = [random.randint(0, 255) for i in range(10)]
res = "".join(["%02x" % item for item in byte_list])
print(res)
import random
res = "".join(["%02x" % random.randint(0, 255) for i in range(10)])
print(res)
1.4 时间戳
抖音:_ticket
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);
System.out.println(t2);
}
}
import time
v1 = int(time.time()) // 秒级别
v2 = int(time.time()*1000) # 毫秒级别
v1 = str(int(time.time()))
v2 = str(int(time.time()*1000))
1.5 十六进制的字符串
在Java中字节是有符号:-128 ~ 127
# name_bytes = "武沛齐".encode('utf-8')
name_bytes = [10, -26, -83, -90, -26, -78, -101, -23, -67, -112]
data_list = []
for item in name_bytes:
item = item & 0xff # item<0时,让item+256
ele = "%02x" % item # 转为16进制
data_list.append(ele)
print("".join(data_list))
s='pengyuyan'.encode('utf-8')
l=[]
for i in s:
l.append(hex(i)[2:].rjust(2,'0')) # 转16进制,只去后两位,如果不足两位,补0
print(l)
1.6 md5加密
import hashlib
obj = hashlib.md5()
obj.update('xxxxx'.encode('utf-8'))
# java中没有这个功能。
v1 = obj.hexdigest()
print(v1) # fb0e22c79ac75679e9881e6ba183b354
v2 = obj.digest()
print(v2) # b'\xfb\x0e"\xc7\x9a\xc7Vy\xe9\x88\x1ek\xa1\x83\xb3T'
抖音:X-SS-STUB
每次发送POST请求时,抖音都会携带一些请求头:
X-SS-STUB = "fjaku9asdf"
读取请求体中的数据,对请求体中的数据进行md5加密。
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
public class Hello {
public static void main(String[] args) throws NoSuchAlgorithmException {
String name = "武沛齐";
MessageDigest instance = MessageDigest.getInstance("MD5");
byte[] nameBytes = instance.digest(name.getBytes());
// 十六进制展示
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); // e6ada6e6b29be9bd90
}
}
import hashlib
m = hashlib.md5()
m.update("武沛齐".encode("utf-8"))
v1 = m.digest()
print(v1) # b'\x175\x10\x12G$)\xd5-\x0c\r#\xd4h\x17='
v2 = m.hexdigest()
print(v2) # 17351012472429d52d0c0d23d468173d
关于加盐:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
public class Hello {
public static void main(String[] args) throws NoSuchAlgorithmException {
String name = "武沛齐";
MessageDigest instance = MessageDigest.getInstance("MD5");
instance.update("xxxxxx".getBytes());
byte[] nameBytes = instance.digest(name.getBytes());
System.out.println(Arrays.toString(nameBytes));
String res = new String(nameBytes);
System.out.println(res);
// 十六进制展示
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); // e6ada6e6b29be9bd90
}
}
import hashlib
m = hashlib.md5("xxxxxx".encode('utf-8'))
m.update("武沛齐".encode("utf-8"))
v2 = m.hexdigest()
print(v2) # 17351012472429d52d0c0d23d468173d
1.7 sha-256加密
B站:x/report/andriod2,请求体
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
public class Hello {
public static void main(String[] args) throws NoSuchAlgorithmException {
String name = "武沛齐";
MessageDigest instance = MessageDigest.getInstance("SHA-256");
byte[] nameBytes = instance.digest(name.getBytes());
// System.out.println(Arrays.toString(nameBytes));
// String res = new String(nameBytes);
// System.out.println(res);
// 十六进制展示
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); // e6ada6e6b29be9bd90
}
}
import hashlib
m = hashlib.sha256()
m.update("武沛齐".encode("utf-8"))
v2 = m.hexdigest()
print(v2)
1.8 AES加密
对称加密
- key & iv ,明文加密。【app端】
- key & iv ,解密。【API】
情况A: 请求体密文(抓包乱码)
情况B: sign,AES加密+base64编码
刷B站播放时,发送POST请求。
AES加密(请求体中的数据) -> 密文(JS央视频 key & iv & 加密)。
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
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));
}
}
# pip install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
KEY = "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)
print([ i for i in data])
1.9 gzip压缩
抖音注册设备:设备。
注册设备:生成一些值,值中包括: (cdid、手机型号、手机品牌....) 后端读取到时候,发现cdid是一个全新的请求。那么抖音就会生成
device_id、install_id、tt
(cdid、手机型号、手机品牌....) --> gzip压缩(字节) --> 加密 --> 密文
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.io.OutputStream;
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();
// [11,22,31,14,45]
byte[] arg6 = v0_1.toByteArray(); //gzip压缩后:arg6
// System.out.println(Arrays.toString(arg6));
// 解压缩
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"));
}
}
import gzip
# 压缩
"""
s_in = "我是武沛齐".encode('utf-8')
s_out = gzip.compress(s_in)
print([i for i in s_out])
"""
# 解压缩
"""
res = gzip.decompress(s_out)
print(res)
print(res.decode('utf-8'))
"""
提醒:java、Python语言区别。(个人字节是不同,不影响整个的结果),。
1.10 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()); // name.getBytes()相当于python中encode('utf-8')
System.out.println(res); // "5q2m5rKb6b2Q"
// 解密
Base64.Decoder decoder = Base64.getDecoder();
byte[] origin = decoder.decode(res);
String data = new String(origin);
System.out.println(data); // 武沛齐
}
}
import base64
name = "武沛齐"
res = base64.b64encode(name.encode('utf-8'))
print(res) # b'5q2m5rKb6b2Q'
data = base64.b64decode(res)
origin = data.decode('utf-8')
print(origin) # "武沛齐"
# 不同,换行符 + ==