java常用加密手段

虽然一般都会给APK上壳。但是拖壳还是要分析JAVa
链接:https://pan.baidu.com/s/1Qm0cF0u7RCGy174QYeVf2Q?pwd=c60g
提取码:c60g

1.隐藏字节

-将明文字符串->转为字节定义

public static void main(String[] args) throws IOException {

    String strq=new String(new byte[]{97,115,98,100});
    String str=strq.toString();
    /*
    byte[] bytesstr=str.getBytes();
    String stra= Arrays.toString(bytesstr);
    */

    ///[97, 115, 98, 100]

    System.out.println(str);
    FileOutputStream fileOutputStream=new FileOutputStream("out.txt");
    fileOutputStream.write(str.getBytes());


}

py

# 字节列表
byte_list = [26, 83, 90, 26, 78, 101, 23, 67, 112]

# 字节列表 -> python的字节数组
bs = bytearray()
for item in byte_list:
    bs.append(item)
    
# 将字节数组解码为字符串,使用 UTF-8 编码。
str_data = bs.decode('utf-8')
print(str_data)
2.uuid加密

image-20240510184433100

例如抖音请求的uuid-截取uuid字符串

int desiredLength = 8; // 指定位数

// 生成 UUID 字符串
String uuid = UUID.randomUUID().toString();

// 去除 UUID 中的连接符 "-"
String uuidWithoutHyphens = uuid.replace("-", "");

// 截取指定位数的 UUID 子字符串
String truncatedUUID = uuidWithoutHyphens.substring(0, desiredLength);

System.out.println("Truncated UUID: " + truncatedUUID);

伪造uuid

uuid-是随机的-但是可能会根据用户设备ID来随机uuid
 第一种:每次请求生成UUID,抓包,每次都不一样 --> 直接伪造。
 
 - 第二种:--设备验证功能
 - 在app刚启动,偷偷向后端发送请求,返回uuid,手机的凭证
	- app写入到本地文件 xxx.xml
	- 点击功能,发送请求 + 找到文件uuid -> 发送过去


	现象:
		- 抓包uuid固定
		- app清楚数据 & 卸载安装 -> uuid会变
		
思路:
		- 直接用固定的uuid
		- 动态生成是否能用?
		- 过程模拟
			- 启动请求,获取uuid
			- 发送请求携带
3.随机值

抖音:openudid

image-20240510185058992

String hex16=new BigInteger(80,new SecureRandom()).toString(16);
4.时间戳
String t2 = String.valueOf(System.currentTimeMillis());
String t1 = String.valueOf(System.currentTimeMillis() / 1000);
5.十六进制字符串
        int[] byte_list = {1, -26, -83, -9, -26, -78, -101, -23, -67, -112};
        StringBuilder stringBuilder=new StringBuilder();
        int byte_size=byte_list.length;
        for(int by:byte_list)
        {
            by=by&0xff;//有符合转无符号 +250
            //不满两位补0--保证位数整齐
            if(by<16)
            {
                stringBuilder.append(by);
            }
            stringBuilder.append(Integer.toHexString(by & 0xFF)); // 转换为十六进制字符串
        }
        System.out.println(stringBuilder);
6.MD5加密

抖音:X-SS-STUB

每次发送POST请求时,抖音都会携带一些请求头:
X-SS-STUB = "fjaku9asdf"

读取请求体中的数据,对请求体中的数据进行md5加密。

image-20240510192340825

String str="wsnbb";
MessageDigest messageDigest=MessageDigest.getInstance("md5");
messageDigest.update(str.getBytes("UTF-8"));
byte[] digest = messageDigest.digest();
StringBuilder stringBuilder = new StringBuilder();
for (byte b : digest) {
    stringBuilder.append(String.format("%02x", b & 0xff));
}
String hashText = stringBuilder.toString();
System.out.println(hashText);
String str="123456";
MessageDigest messageDigest=MessageDigest.getInstance("md5");
messageDigest.update(str.getBytes("UTF-8"));

//获取字节
byte[] digest = messageDigest.digest();
//可变字符串
StringBuilder stringBuilder = new StringBuilder();
for (byte b : digest) {
    int b16=b&255;//有符合转无符号
    if(b16<16)//字节补全-MD5定长
    {
        stringBuilder.append(0);
    }
    stringBuilder.append(Integer.toHexString(b16));//转16进制

}
String hashText = stringBuilder.toString();
System.out.println(hashText);
7.sha-256加密
MessageDigest messageDigest=MessageDigest.getInstance("SHA-256");
8.AES加密
  • key & iv ,明文加密。【app端】

  • key & iv ,解密。【API】

    情况A: 请求体密文(抓包乱码)
    情况B: sign,AES加密+base64编码

   String data="不该";
   String key="fd6b639dbcff0c2a1b03b389ec763c4b";
   String iv="77b07a672d57d64c";
  byte[] rawkey = key.getBytes();
//用于包装密钥 --包装向量
        SecretKeySpec AES=new SecretKeySpec(rawkey,"AES");
        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
//指定加密
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//加密
        cipher.init(Cipher.ENCRYPT_MODE, AES, ivSpec);
        
        byte[] encrypted = cipher.doFinal(data.getBytes());
9.gzip压缩

抖音注册设备:设备。

注册设备:生成一些值,值中包括: (cdid、手机型号、手机品牌....) 后端读取到时候,发现cdid是一个全新的请求。那么抖音就会生成 device_id、install_id、tt

(cdid、手机型号、手机品牌....) --> gzip压缩(字节) --> 加密 --> 密文

    String data = "HASH-RMPC";
        //字符串这里就不加密了-抖音会对该文件加密 字节数组输出流,用于存储压缩后的数据
        ByteArrayOutputStream v0_1 = new ByteArrayOutputStream();
        ///将数据压缩后写入到字节数组输出流中
        GZIPOutputStream v1 = new GZIPOutputStream((v0_1));
        v1.write(data.getBytes());
        v1.close();
        //写入压缩文件
        byte[] arg6 = v0_1.toByteArray();
        FileOutputStream fileOutputStream = new FileOutputStream("gzip.zip");
        fileOutputStream.write(arg6);


        //从字节数组中读取数据的类
        // ByteArrayInputStream v_read=new ByteArrayInputStream("gzip.zip".getBytes());
        FileInputStream fileInputStream = new FileInputStream("gzip.zip");
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int byteRead;
        while ((byteRead = fileInputStream.read()) != -1) {
            byteArrayOutputStream.write(byteRead);
        }
        byte[] byteArray = byteArrayOutputStream.toByteArray();
//GZIPOutputStream 压缩的是二进制数据,
// 而不是纯文本数据。因此,你不能简单地将压缩后的字节数组转换为字符串,并期望得到可读的文本内容。
        //从这个字节数组中读取数据的流对象
 ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);

        GZIPInputStream gzipInputStream = new GZIPInputStream(byteInputStream);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = gzipInputStream.read(buffer)) > 0) {
            out.write(buffer, 0, len);
        }

        System.out.println(out.toString("UTF-8"));
10.base64编码
        String name = "武沛齐";
        // 加密
        ///创建了一个 Base64 编码器对象,使用 Base64.getEncoder() 方法获取。
        Base64.Encoder encoder  = Base64.getEncoder();

        String res = encoder.encodeToString(name.getBytes());
        System.out.println(res); // "5q2m5rKb6b2Q"

        // 解密
        Base64.Decoder encoder1=Base64.getDecoder();
        byte[] decode = encoder1.decode(res.getBytes());
        String data = new String(decode);
        System.out.println(data); // 武沛齐
posted @ 2024-05-11 10:42  逆向狗  阅读(84)  评论(0)    收藏  举报