标签 java 下的文章

乐尚视界APP数据包加解密脚本

突然看到一个APP叫乐尚视界,能看十几个网站的vip视频,感觉和之前的网页在线观看vip视频没有实名区别。
在抓包的时候发现了APP对数据包进行了加密,对APP进行反编译后,一边练手一边写出下面的加解密脚本,仅供参考。

/*
 * Copyright sky 2018-01-18 Email:sky@03sec.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.javaweb.demo;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.*;
import java.util.Base64;

public class LeeShang {


    public static String aaaaa(String var0) {
        byte[] var3;
        try {
            var3 = MessageDigest.getInstance("md5").digest(var0.getBytes());
        } catch (NoSuchAlgorithmException var2) {
            throw new RuntimeException("没有md5这个算法!");
        }

        var0 = (new BigInteger(1, var3)).toString(16);

        for (int var1 = 0; var1 < 32 - var0.length(); ++var1) {
            var0 = "0" + var0;
        }

        return var0;
    }

    public static byte[] encrypt(byte[] paramArrayOfByte, String password, String secureRandom) {
        try {
            SecretKeySpec keySpec     = secretKeySpec(password);
            Cipher        localCipher = Cipher.getInstance("AES/CBC/NoPadding");
            while (paramArrayOfByte.length % 16 != 0) { //如果paramArrayOfByte的长度不是16的倍数AES加密会报错,这边对paramArrayOfByte进行长度扩展,使它必须为16的倍数
                byte[] tmpByte = {0x00};
                paramArrayOfByte = ByteBuffer.allocate(paramArrayOfByte.length + 1).put(tmpByte).array();
            }
            localCipher.init(2, keySpec, ivParameterSpec(secureRandom));
            paramArrayOfByte = localCipher.doFinal(paramArrayOfByte);
            return paramArrayOfByte;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] decrypt(byte[] content, String password, String secureRandom) {
        try {
            SecretKeySpec keySpec = secretKeySpec(password);
            Cipher        cipher  = Cipher.getInstance("AES/CBC/NoPadding");// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec(secureRandom));// 初始化
            byte[] result = cipher.doFinal(content);
            return result; // 加密
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static SecretKeySpec secretKeySpec(String var0) {
        Object var2 = null;
        String var1 = var0;
        if (var0 == null) {
            var1 = "";
        }

        StringBuffer var4 = new StringBuffer(16);
        var4.append(var1);

        while (var4.length() < 16) {
            var4.append("0");
        }

        if (var4.length() > 16) {
            var4.setLength(16);
        }

        byte[] var5;
        try {
            var5 = var4.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException var3) {
            var3.printStackTrace();
            var5 = (byte[]) var2;
        }

        return new SecretKeySpec(var5, "AES");
    }


    private static IvParameterSpec ivParameterSpec(String var0) {
        Object var2 = null;
        String var1 = var0;
        if (var0 == null) {
            var1 = "";
        }

        StringBuffer var4 = new StringBuffer(16);
        var4.append(var1);

        while (var4.length() < 16) {
            var4.append("0");
        }

        if (var4.length() > 16) {
            var4.setLength(16);
        }

        byte[] var5;
        try {
            var5 = var4.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException var3) {
            var3.printStackTrace();
            var5 = (byte[]) var2;
        }

        return new IvParameterSpec(var5);
    }

    public static String convertByteArrayToString(byte[] var1) {

        String value = new String(var1);
        return value;
    }

    public static void main(String[] args) {
        String key          = "$75k!xxH&$EhQLmv";
        String secureRandom = aaaaa("$75k!xxH&$EhQLmv").substring(0, 16);
        //解密
        String content      = "jStVIqaSUdIm0aF8mcs8GAjohYApwOUYVXenyG7zeQV86ZFrmO3Z1ixPLEM9srKRaVR1nE+0V3gTKGtlgwWgCg==";
        System.out.println(convertByteArrayToString(decrypt(Base64.getDecoder().decode(content), key, secureRandom)));
        //加密
        String s = "{'token':'x','code':'ghhhh'}";
        System.out.println(Base64.getEncoder().encodeToString(encrypt(s.getBytes(), key, secureRandom)));
    }
}

Java中isAssignableFrom()方法与instanceof()方法用法

一句话总结:

  • isAssignableFrom()方法是从类继承的角度去判断,instanceof()方法是从实例继承的角度去判断。
  • isAssignableFrom()方法是判断是否为某个类的父类,instanceof()方法是判断是否某个类的子类。
    ### 1. Class.isAssignableFrom()方法
    Class.isAssignableFrom()是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的子类或接口。
    格式为:
Class1.isAssignableFrom(Class2) 

调用者和参数都是java.lang.Class类型。

2.Class.instanceof()方法

Class.instanceof()是用来判断一个对象实例是否是一个类或接口的或其子类子接口的实例。

格式是:

obj instanceof TypeName  

第一个参数是对象实例名,第二个参数是具体的类名或接口名,例如 String,InputStream。其返回值为boolean。

3.具体用法

转自(http://sunnylocus.iteye.com/blog/555676)

package com.bill99.pattern;

public class AssignableTest {
    
    public AssignableTest(String name) {
    }
    /**
     * 判断一个类是否是另一个类的父类
     * 是打印true
     * 否打印false
     */
    public static void testIsAssignedFrom1() {
        System.out.println("String是Object的父类:"+String.class.isAssignableFrom(Object.class));
    }
    /**
     * 判断一个类是否是另一个类的父类
     * 是打印true
     * 否打印false
     */
    public static void testIsAssignedFrom2() {
        System.out.println("Object是String的父类:"+Object.class.isAssignableFrom(String.class));
    }
    /**
     * 判断一个类是否和另一个类相同
     * 是打印true
     * 否打印false
     */
    public static void testIsAssignedFrom3() {
        System.out.println("Object和Object相同:"+Object.class.isAssignableFrom(Object.class));
    }

    /**
     * 判断str是否是Object类的实例
     * 是打印true
     * 否打印false
     */
    public static void testInstanceOf1() {
        String str = new String();
        System.out.print("str是Object的实例:");
        System.out.println(str instanceof Object);
    }
    /**
     * 判断o是否是Object类的实例
     * 是打印true
     * 否打印false
     */
    public static void testInstanceOf2() {
        Object o = new Object();
        System.out.print("o是Object的实例:");
        System.out.println(o instanceof Object);
    }
    
    public static void main(String[] args) {
        testIsAssignedFrom1();
        testIsAssignedFrom2();
        testIsAssignedFrom3();
        testInstanceOf1();
        testInstanceOf2();
    }
}

结果:

String是Object的父类:false
Object是String的父类:true
Object和Object相同:true
str是Object的实例:true
o是Object的实例:true

批量反编译jar包

  • 首先把jar包改为后缀rar,然后进行解压。

解压过程中可能会报错,忽略即可

然后在终端输入下列命令进行批量反编译(xxx是上面rar解压出来的目录)

jad -r -ff -d src -s java xxx/**/*.class

这边有个坑,如果你是macos配置的zsh终端,那可能会提示下面这段话

zsh: argument list too long: jad

解决办法:
临时切换为bash,然后使用命令进行反编译

MAC JDK版本切换

通过命令'jdk7', 'jdk8'轻松切换到对应的Java版本:

  • 1.首先安装所有的JDk



    • Mac自带了的JDK6,安装在目录:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/下。
    • JDK7,JDK8,JDK9则需要自己到Oracle官网下载安装对应的版本。自己安装的JDK默认路径为:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk
  • 2.配置
    编辑~/.zshrc文件(我是zsh的shell,所有配置该文件,如果是bash,则配置.bash_profile)

在最下面加入下面的代码

#设置jdk版本
export JAVA_7_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home
export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home


#alias命令动态切换JAVA_HOME的配置
alias jdk7='export JAVA_HOME=$JAVA_7_HOME'
alias jdk8='export JAVA_HOME=$JAVA_8_HOME'


export JAVA_HOME=$JAVA_7_HOME

输入完成后保存,然后执行下面命令

source ~/.zshrc
  • 3.验证

使用:jdk7、jdk8即可切换jdk版本

java反编译

jad.exe文件,将它设置到环境变量path,(复制到 %JAVA_HOME%\BIN的目录下)
或者拷到其他已经了环境变量path的地方,或者在cmd中转到此文件目录下。

简单的方法是

jad -o -r -d F:\src -s java F:\classes\**\*.class 

-o - overwrite output files without confirmation (default: no) 无需确定覆写文件

-r - restore package directory structrure 恢复包目录结构

-s - output file extension (by default '.jad') 如果不设置为-s java,则默认扩展名为.jad

其他的,F:\classes***.class 中的两颗接连的星,表示任意层次的子目录