字节码加密

字节码加密

方案1:使用工具ClassFinal

使用工具ClassFinal
说明:ClassFinal是一款java class文件安全加密工具,支持直接加密jar包或war包,无需修改任何项目代码,兼容spring-framework;可避免源码泄漏或字节码被反编译。
目前项目处于暂停状态

使用方式

1. 命令行方式

java -jar classfinal-fatjar.jar -file yourpaoject.jar -libjars a.jar,b.jar -packages com.yourpackage,com.yourpackage2 -exclude com.yourpackage.Main -pwd 123456 -Y

参数说明
-file        加密的jar/war完整路径
-packages    加密的包名(可为空,多个用","分割)
-libjars     jar/war包lib下要加密jar文件名(可为空,多个用","分割)
-cfgfiles    需要加密的配置文件,一般是classes目录下的yml或properties文件(可为空,多个用","分割)
-exclude     排除的类名(可为空,多个用","分割)
-classpath   外部依赖的jar目录,例如/tomcat/lib(可为空,多个用","分割)
-pwd         加密密码,如果是#号,则使用无密码模式加密
-code        机器码,在绑定的机器生成,加密后只可在此机器上运行
-Y           无需确认,不加此参数会提示确认以上信息
2. maven插件方式

在要加密的项目pom.xml中加入以下插件配置,目前最新版本是:1.2.1。

<plugin>
    <!-- https://gitee.com/roseboy/classfinal -->
    <groupId>net.roseboy</groupId>
    <artifactId>classfinal-maven-plugin</artifactId>
    <version>${classfinal.version}</version>
    <configuration>
        <password>000000</password><!--加密打包之后pom.xml会被删除,不用担心在jar包里找到此密码-->
        <packages>com.yourpackage,com.yourpackage2</packages>
        <cfgfiles>application.yml</cfgfiles>
        <excludes>org.spring</excludes>
        <libjars>a.jar,b.jar</libjars>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>classFinal</goal>
            </goals>
        </execution>
    </executions>
</plugin>

运行mvn package时会在target下自动加密生成yourpaoject-encrypted.jar。
maven插件的参数名称与直接运行的参数相同,请参考上节的参数说明。

示例:
比如源码:

@RestController
@RequestMapping("user")
public class UserController {

    @GetMapping("get")
    public String get(){
        System.out.println("hello world");
        return "user";
    }
}

加密之后的源码:

@RestController
@RequestMapping({"user"})
public class UserController {
    public UserController() {
    }

    @GetMapping({"get"})
    public String get() {
        return null;
    }
}

注意: 原始的class文件并不会完全被加密,只是方法体被清空,保留方法参数、注解等信息,这是为了兼容spring,swagger等扫描注解的框架; 方法体被清空后,反编译者只能看到方法名和注解,看不到方法的具体内容;当class被classloader加载时,真正的方法体会被解密注入。

方案2:使用Protector4J

官网地址:Protector4J

说明:收费java字节码加密工具

  1. 支持 windows、Linux、macOS

  2. 费用:

项目599/Y1099/Y3099/Y
For Individual Use
JavaSE Apps Protection
Tomcat Apps Protection
Spring Boot Apps Protection
Email Support
Live Chat Support (Slack)
Windows/Linux Service Creator
Docker Image Creator
Apple Silicon Support
Local Deployment (Encrypt without Internet)
  1. 参考文档:https://protector4j.com/docs
  2. 加密之后运行项目 jar:
# 默认加密之后的jar存放在vlxlib目录中
vlxjre/bin/java -jar vlxlib/xxx.jar

# 或者:
vlxjre/bin/java -cp vlxlib/xxx.jar MainClass

字节码混淆

方式1:ProGuard

介绍:

ProGuard 是一个开源的 Java 类文件压缩器、优化器、混淆器和预验证器。因此,ProGuard 处理的应用程序和库更小、更快,并且在一定程度上增强了逆向工程的能力。
文档:https://www.guardsquare.com/manual/
github:https://github.com/Guardsquare/proguard/

maven使用方式:

<plugin>
    <groupId>com.github.wvengen</groupId>
    <artifactId>proguard-maven-plugin</artifactId>
    <version>2.0.14</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>proguard</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <!-- 将混淆后的pg包自动部署到maven上-->
        <attach>true</attach>
        <attachArtifactClassifier>pg</attachArtifactClassifier>
        <!-- attach 的作用是在 install 与 deploy 时将生成的 pg 文件也安装与部署 -->
        <options>
            <!-- JDK目标版本1.6-->
            <option>-target 1.6</option>
            <!-- 不做收缩(删除注释、未被引用代码)-->
            <option>-dontshrink</option>
            <!-- 不做优化(变更代码实现逻辑)-->
            <option>-dontoptimize</option>
            <!-- 不路过非公用类文件及成员-->
            <option>-dontskipnonpubliclibraryclasses</option>
            <option>-dontskipnonpubliclibraryclassmembers</option>
            <!-- 优化时允许访问并修改有修饰符的类和类的成员 -->
            <option>-allowaccessmodification</option>
            <!-- 确定统一的混淆类的成员名称来增加混淆-->
            <option>-useuniqueclassmembernames</option>
 
            <!--保证spring注解能力-->
            <!--<option>-keepdirectories</option>-->
 
            <!-- 不混淆所有包名,本人测试混淆后WEB项目问题实在太多,毕竟Spring配置中有大量固定写法的包名-->
            <option>-keeppackagenames</option>
            <!-- 不混淆所有特殊的类-->
            <option>-keepattributes
                Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
            </option>
            <!-- 不混淆所有的set/get方法,毕竟项目中使用的部分第三方框架(例如Shiro)会用到大量的set/get映射-->
            <option>-keepclassmembers public class * {void set*(***);*** get*();}</option>
 
            <!-- 不混淆commonmodel,model包中的所有类以及类的属性及方法,实体包,混淆了会导致前端无法识别-->
            <!--<option>-keep class com.xxx.web.commonmodel.** {*;}</option>-->
            <!--<option>-keep class com.xxx.web.model.** {*;}</option>-->
 
            <!--不混淆JNI相关接口-->
            <!--<option>-keep class com.xxx.dasheng_cluster.service.** {*;}</option>-->
            <!--<option>-keep class com.xxx.dasheng_selfsampling.service.** {*;}</option>-->
 
            <!-- 非核心业务类,不作混淆 -->
 
            <!--<option>-keep class com.xxx.web.util.** {*;}</option>-->
            <!--<option>-keep class com.xxx.web.Swagger2 {*;}</option>-->
 
            <!-- 以下三个包因为大部分是Spring管理的Bean,不对包类的类名进行混淆,但对类中的属性和方法混淆-->
            <!--<option>-keep class com.xxx.web.controller.**</option>-->
            <!--<option>-keep class com.xxx.web.service.**</option>-->
            <!--<option>-keep class com.xxx.web.singleton.**</option>-->
 
            <!-- 不混淆凭证包下的所有类名,但对类中的属性、方法进行混淆-->
            <option>-keep class com.jd.ssa.client.interceptor.** {*;}</option>
            <option>-keep class com.jd.ssa.client.service.** {*;}</option>
            <option>-keep class com.jd.ssa.client.LoginContext {*;}</option>
            <option>-keep class com.lopSdk.** {*;}</option>
 
            <!-- 不混淆启动类,否则spring-boot不能正常启动 -->
            <!--<option>-keep class com.xxx.web.Application</option>-->
 
            <!-- 忽略打包时的告警信息 -->
            <option>-ignorewarnings</option>
 
        </options>
        <!-- 输出目录-->
        <outjar>${project.build.finalName}-pg.jar</outjar>
        <!-- 添加依赖,这里你可以按你的需要修改,这里测试只需要一个JRE的Runtime包就行了 -->
        <libs>
            <lib>${java.home}/lib/rt.jar</lib>
            <lib>${java.home}/lib/jce.jar</lib>
        </libs>
        <!-- 加载文件的过滤器,就是你的工程目录了-->
        <!--<inFilter>com/xxx/dasheng/**</inFilter>-->
        <!-- 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧-->
        <!--<injar>classes</injar>-->
        <!-- 输出pom文件 -->
        <addMavenDescriptor>true</addMavenDescriptor>
        <!-- 输出目录-->
        <outputDirectory>${project.build.directory}</outputDirectory>
    </configuration>
</plugin>

参考文档:

  1. java字节码加密
  2. 如何防止 Java 源码被反编译
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值