• Spring boot使用ProGuard实现代码混淆


    代码混淆常见于安卓的apk安装文件, 服务端的代码因为不易被普通用户接触到, 所以混淆不多。但是某些场景下, 比如:项目需要部署到客户机器上, 就会有泄露代码逻辑的风险。
    不过需要知道的是:使用proguard混淆代码只能增加阅读和理解的难度, 并不能百分百保证代码安全。也即是达到让开发人员看到这头痛的代码有99.99999%的冲动放弃阅读,拍桌子说还不如我重写一遍逻辑。

    一、 ProGuard简介

    附:proGuard官网

    因为Java代码是非常容易反编译,况且Springboot和Android开发的应用程序都是用Java代码写的,为了很好的保护Java源代码,我们需要对编译好后的class文件进行混淆。

    ProGuard是一个混淆代码的开源项目,它的主要作用是混淆代码,殊不知ProGuard还包括以下4个功能:

    1. 压缩(Shrink):检测并移除代码中无用的类、字段、方法和特性(Attribute)。
    2. 优化(Optimize):对字节码进行优化,移除无用的指令。
    3. 混淆(Obfuscate):使用a,b,c,d这样简短而无意义的名称,对类、字段和方法进行重命名。
    4. 预检(Preveirfy):在Java平台上对处理后的代码进行预检,确保加载的class文件是可执行的。

    二、混淆配置要点

    1. 建议逐个java包定义混淆规则,这样思路更清晰 ;
    2. repository(dao)层需要保存包名和类名,因为Mybatis的xml文件中引用了dao层的接口 ;
    3. controller层注意在使用@PathVariable、@RequestParam时需要显式声明参数名 ;
    4. dao层用于映射数据库表的类和controller层映射前台参数的类,都需要保留类成员 ;
    5. 修改spring的bean命名策略,改成按类的全限定名来命名。

    三、快速开始

    本文基于springboot2.x + maven + proguard进行代码混淆。
    将源码打包做代码混淆还有其他方案,但是没成功,最终选择proguard,开始使用遇到各种问题,各种jar包版本问题,尝试了5次不同方案,费了十牛二虎之力最终成功,Mark一下。

    3.1 方案

    proguard是最为广为使用的工具之一,可是用他的客户端方式来混淆springboot项目的时候最后总得不到可执行的jar。后来发现了proguard-maven-plugin这个插件,所有proguard的指令都可以在pom中定义实现,本文采用proguard-maven-plugin方案。

    3.2 POM文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.erbadagang.data.jpa</groupId>
        <artifactId>jpa</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>jpa</name>
        <description>JPA project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jdbc</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <!--MySQL数据库连接-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.12</version>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>${spring-boot.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
    
                <!-- proguard混淆插件-->
                <plugin>
                    <groupId>com.github.wvengen</groupId>
                    <artifactId>proguard-maven-plugin</artifactId>
                    <version>2.2.0</version>
                    <executions>
                        <execution>
                            <!-- 打包的时候开始混淆-->
                            <phase>package</phase>
                            <goals>
                                <goal>proguard</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <injar>${project.build.finalName}.jar</injar>
                        <!--输出的jar-->
                        <outjar>${project.build.finalName}.jar</outjar>
                        <!-- 是否混淆-->
                        <obfuscate>true</obfuscate>
                        <options>
                            <option>-target 1.8</option> <!--指定java版本号-->
                            <option>-dontshrink</option> <!--默认开启,不做收缩(删除注释、未被引用代码)-->
                            <option>-dontoptimize</option><!--默认是开启的,这里关闭字节码级别的优化-->
                            <option>-adaptclassstrings</option><!--混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代-->
                            <option>-ignorewarnings
                            </option><!-- 忽略warn消息,如果提示org.apache.http.* 这个包里的类有问题,那么就加入下述代码:-keep class org.apache.http.** { *; }    -dontwarn org.apache.http.**-->
                            <option>-keep class org.apache.logging.log4j.util.* { *; }</option>
                            <option>-dontwarn org.apache.logging.log4j.util.**</option>
                            <option>-keepattributes
                                Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
                            </option><!--对异常、注解信息在runtime予以保留,不然影响springboot启动-->
                            <!--不混淆所有interface接口-->
                            <!--                        <option>-keepnames interface **</option>-->
                            <option>-keepclassmembers enum * { *; }</option><!--保留枚举成员及方法-->
                            <option>-keepparameternames</option>
                            <option>-keepclasseswithmembers public class * {
                                public static void main(java.lang.String[]);}
                            </option> <!--保留main方法的类及其方法名-->
                            <!--忽略note消息,如果提示javax.annotation有问题,那麽就加入以下代码-->
                            <option>-dontnote javax.annotation.**</option>
                            <option>-dontnote sun.applet.**</option>
                            <option>-dontnote sun.tools.jar.**</option>
                            <option>-dontnote org.apache.commons.logging.**</option>
                            <option>-dontnote javax.inject.**</option>
                            <option>-dontnote org.aopalliance.intercept.**</option>
                            <option>-dontnote org.aopalliance.aop.**</option>
                            <option>-dontnote org.apache.logging.log4j.**</option>
    
                            <!--  ##### 以下为需要根据项目情况修改 comment by 郭秀志 20200719 ##### -->
                            <!--入口程序类不能混淆,混淆会导致springboot启动不了-->
                            <option>-keep class com.erbadagang.data.jpa.JpaApplication</option>
                            <option>-keep class com.erbadagang.data.jpa.base.* {*;}</option>
                            <option>-keep class com.erbadagang.data.jpa.entity.* {*;}</option>
                            <option>-keep class com.erbadagang.data.jpa.model.* {*;}</option>
                            <option>-keep class com.erbadagang.data.jpa.controller.* {*;}</option>
                            <!--  ##### 以上为需要根据项目情况修改  comment by 郭秀志 20200719 ##### -->
    
                            <option>-keep interface * extends * { *; }</option>
                            <!--不混淆所有类,保存原始定义的注释-->
                            <option>-keepclassmembers class * {
                                @org.springframework.beans.factory.annotation.Autowired *;
                                @org.springframework.beans.factory.annotation.Value *;
                                }
                            </option>
                        </options>
                        <libs>
                            <!-- 添加依赖 java8-->
                            <lib>${java.home}/lib/rt.jar</lib>
                            <lib>${java.home}/lib/jce.jar</lib>
                        </libs>
                    </configuration>
                    <dependencies>
                        <!-- https://mvnrepository.com/artifact/net.sf.proguard/proguard-base -->
                        <dependency>
                            <groupId>net.sf.proguard</groupId>
                            <artifactId>proguard-base</artifactId>
                            <version>6.1.1</version>
                        </dependency>
                    </dependencies>
                </plugin>
    
                <!--Springboot repackage 打包-->
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <!-- spingboot 打包需要repackage否则不是可执行jar -->
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                            <configuration>
                                <mainClass>com.erbadagang.data.jpa.JpaApplication</mainClass>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    直接在项目中将自己打包部分<build>......</build>的maven plugin(插件)替换成上面的代码即可,各个插件的作用已经注释。

    下面这些代码是用来指定哪些包不被混淆,注意将包路径改为你自己的,为了纪念小时候的神车“二八大杠”,我的包名统统以erbadagang作为前缀。

    <!--  ##### 以下为需要根据项目情况修改 comment by 郭秀志 20200719 ##### -->
    <!--入口程序类不能混淆,混淆会导致springboot启动不了-->
    <option>-keep class com.erbadagang.data.jpa.JpaApplication</option>
    <option>-keep class com.erbadagang.data.jpa.base.* {*;}</option>
    <option>-keep class com.erbadagang.data.jpa.entity.* {*;}</option>
    <option>-keep class com.erbadagang.data.jpa.model.* {*;}</option>
    <option>-keep class com.erbadagang.data.jpa.controller.* {*;}</option>
    <!--  ##### 以上为需要根据项目情况修改  comment by 郭秀志 20200719 ##### --> 
    

    说明:
    -keep class 类/包.** 表示保留类名;
    -keepclassmembers class 类/包.**{ *;} 表示保留类下边的所有变量,均不混淆。

    另外需要注意的点, shrink这个功能一般最好别用,所以这里添加了<option>-dontshrink</option>,我就遇到过启动jar的时候不支持压缩jar的问题。

    在使用客户端的时候经常会出现warings之类的提示,大多数处理方式都是使用-ignorewarings这个被官方指令来解决的,但是好多文章或参考资料中都有说明,这可能会带来一些问题。

    网上很多地方是把指令写在一个外部proguard.conf来实现的,但是我用那些方法的一直没有成功,所以直接把配置写在了pom文件。

    3.3 更换bean命名策略(本文未使用)

    bean命名重复异常,由于proguard混淆貌似不能指定在basePackages下面类名混淆后唯一,不同包名经常有a.class,b.class,c.class之类重复的类名,因此spring容器初始化bean的时候会报错。

    org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.example.demo.MvcDemoApplication]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'a' for bean class [com.example.demo.c.a] conflicts with existing, non-compatible bean definition of same name and class [com.example.demo.b.a]
    

    我们可以通过改变spring的bean的命名策略来解决这个问题,把包名带上,就唯一了。本文添加此功能导致jar无法启动,这个解决方案仅作为参考,本文的源代码无这部分功能

    3.4编译打包

    3.4.1 命令行打包

    可以使用命令行方式打包,在项目的pom文件所在文件夹执行mvn clean package -DskipTests

    3.4.2 工具打包

    使用maven进行编译打包,如图选择cleanpackage,然后点击运行Maven编译按钮。

     
    maven进行混淆打包

    如果没有错误,控制台会输出proguard的日志及最后的BUILD SUCCESS提示:

    [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ jpa ---
    [INFO] Building jar: D:\dev\GitRepository\jpa\target\jpa-0.0.1-SNAPSHOT.jar
    [INFO] 
    [INFO] --- proguard-maven-plugin:2.2.0:proguard (default) @ jpa ---
    [INFO] execute ProGuard [-injars, 'D:\dev\GitRepository\jpa\target\jpa-0.0.1-SNAPSHOT_proguard_base.jar'(!META-INF/maven/**), -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-starter-data-jdbc\2.3.0.RELEASE\spring-boot-starter-data-jdbc-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-starter-jdbc\2.3.0.RELEASE\spring-boot-starter-jdbc-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\com\zaxxer\HikariCP\3.4.5\HikariCP-3.4.5.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-jdbc\5.2.6.RELEASE\spring-jdbc-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\data\spring-data-jdbc\2.0.0.RELEASE\spring-data-jdbc-2.0.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\data\spring-data-relational\2.0.0.RELEASE\spring-data-relational-2.0.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\data\spring-data-commons\2.3.0.RELEASE\spring-data-commons-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-tx\5.2.6.RELEASE\spring-tx-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-starter-data-jpa\2.3.0.RELEASE\spring-boot-starter-data-jpa-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-starter-aop\2.3.0.RELEASE\spring-boot-starter-aop-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\aspectj\aspectjweaver\1.9.5\aspectjweaver-1.9.5.jar', -libraryjars, 'D:\dev\mvnRespo\jakarta\transaction\jakarta.transaction-api\1.3.3\jakarta.transaction-api-1.3.3.jar', -libraryjars, 'D:\dev\mvnRespo\jakarta\persistence\jakarta.persistence-api\2.2.3\jakarta.persistence-api-2.2.3.jar', -libraryjars, 'D:\dev\mvnRespo\org\hibernate\hibernate-core\5.4.15.Final\hibernate-core-5.4.15.Final.jar', -libraryjars, 'D:\dev\mvnRespo\org\jboss\logging\jboss-logging\3.4.1.Final\jboss-logging-3.4.1.Final.jar', -libraryjars, 'D:\dev\mvnRespo\org\javassist\javassist\3.24.0-GA\javassist-3.24.0-GA.jar', -libraryjars, 'D:\dev\mvnRespo\net\bytebuddy\byte-buddy\1.10.10\byte-buddy-1.10.10.jar', -libraryjars, 'D:\dev\mvnRespo\antlr\antlr\2.7.7\antlr-2.7.7.jar', -libraryjars, 'D:\dev\mvnRespo\org\jboss\jandex\2.1.3.Final\jandex-2.1.3.Final.jar', -libraryjars, 'D:\dev\mvnRespo\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar', -libraryjars, 'D:\dev\mvnRespo\org\dom4j\dom4j\2.1.3\dom4j-2.1.3.jar', -libraryjars, 'D:\dev\mvnRespo\org\hibernate\common\hibernate-commons-annotations\5.1.0.Final\hibernate-commons-annotations-5.1.0.Final.jar', -libraryjars, 'D:\dev\mvnRespo\org\glassfish\jaxb\jaxb-runtime\2.3.3\jaxb-runtime-2.3.3.jar', -libraryjars, 'D:\dev\mvnRespo\org\glassfish\jaxb\txw2\2.3.3\txw2-2.3.3.jar', -libraryjars, 'D:\dev\mvnRespo\com\sun\istack\istack-commons-runtime\3.0.11\istack-commons-runtime-3.0.11.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\data\spring-data-jpa\2.3.0.RELEASE\spring-data-jpa-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-orm\5.2.6.RELEASE\spring-orm-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-aspects\5.2.6.RELEASE\spring-aspects-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-starter-web\2.3.0.RELEASE\spring-boot-starter-web-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-starter\2.3.0.RELEASE\spring-boot-starter-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot\2.3.0.RELEASE\spring-boot-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-autoconfigure\2.3.0.RELEASE\spring-boot-autoconfigure-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-starter-logging\2.3.0.RELEASE\spring-boot-starter-logging-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar', -libraryjars, 'D:\dev\mvnRespo\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar', -libraryjars, 'D:\dev\mvnRespo\org\apache\logging\log4j\log4j-to-slf4j\2.13.2\log4j-to-slf4j-2.13.2.jar', -libraryjars, 'D:\dev\mvnRespo\org\apache\logging\log4j\log4j-api\2.13.2\log4j-api-2.13.2.jar', -libraryjars, 'D:\dev\mvnRespo\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar', -libraryjars, 'D:\dev\mvnRespo\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar', -libraryjars, 'D:\dev\mvnRespo\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-starter-json\2.3.0.RELEASE\spring-boot-starter-json-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\com\fasterxml\jackson\core\jackson-databind\2.11.0\jackson-databind-2.11.0.jar', -libraryjars, 'D:\dev\mvnRespo\com\fasterxml\jackson\core\jackson-annotations\2.11.0\jackson-annotations-2.11.0.jar', -libraryjars, 'D:\dev\mvnRespo\com\fasterxml\jackson\core\jackson-core\2.11.0\jackson-core-2.11.0.jar', -libraryjars, 'D:\dev\mvnRespo\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.0\jackson-datatype-jdk8-2.11.0.jar', -libraryjars, 'D:\dev\mvnRespo\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.0\jackson-datatype-jsr310-2.11.0.jar', -libraryjars, 'D:\dev\mvnRespo\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.0\jackson-module-parameter-names-2.11.0.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\boot\spring-boot-starter-tomcat\2.3.0.RELEASE\spring-boot-starter-tomcat-2.3.0.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\apache\tomcat\embed\tomcat-embed-core\9.0.35\tomcat-embed-core-9.0.35.jar', -libraryjars, 'D:\dev\mvnRespo\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar', -libraryjars, 'D:\dev\mvnRespo\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.35\tomcat-embed-websocket-9.0.35.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-web\5.2.6.RELEASE\spring-web-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-webmvc\5.2.6.RELEASE\spring-webmvc-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar', -libraryjars, 'D:\dev\mvnRespo\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar', -libraryjars, 'D:\dev\mvnRespo\org\projectlombok\lombok\1.18.12\lombok-1.18.12.jar', -outjars, 'D:\dev\GitRepository\jpa\target\jpa-0.0.1-SNAPSHOT.jar', -libraryjars, 'D:\Program Files\Java\jdk1.8.0_231\jre/lib/rt.jar', -libraryjars, 'D:\Program Files\Java\jdk1.8.0_231\jre/lib/jce.jar', -printmapping, 'D:\dev\GitRepository\jpa\target\proguard_map.txt', -printseeds, 'D:\dev\GitRepository\jpa\target\proguard_seed.txt', -target 1.8, -dontshrink, -dontoptimize, -adaptclassstrings, -ignorewarnings, -keep class org.apache.logging.log4j.util.* { *; }, -dontwarn org.apache.logging.log4j.util.**, -keepattributes
                                Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod, -keepclassmembers enum * { *; }, -keepparameternames, -keepclasseswithmembers public class * {
                                public static void main(java.lang.String[]);}, -dontnote javax.annotation.**, -dontnote sun.applet.**, -dontnote sun.tools.jar.**, -dontnote org.apache.commons.logging.**, -dontnote javax.inject.**, -dontnote org.aopalliance.intercept.**, -dontnote org.aopalliance.aop.**, -dontnote org.apache.logging.log4j.**, -keep class com.erbadagang.data.jpa.JpaApplication, -keep class com.erbadagang.data.jpa.base.* {*;}, -keep class com.erbadagang.data.jpa.entity.* {*;}, -keep class com.erbadagang.data.jpa.model.* {*;}, -keep class com.erbadagang.data.jpa.controller.* {*;}, -keep interface * extends * { *; }, -keepclassmembers class * {
                                @org.springframework.beans.factory.annotation.Autowired *;
                                @org.springframework.beans.factory.annotation.Value *;
                                }]
    [INFO] proguard jar: D:\dev\mvnRespo\net\sf\proguard\proguard-base\6.1.1\proguard-base-6.1.1.jar
     [proguard] ProGuard, version 6.1.1
    ......
     [proguard] Preparing output jar [D:\dev\GitRepository\jpa\target\jpa-0.0.1-SNAPSHOT.jar]
     [proguard]   Copying resources from program jar [D:\dev\GitRepository\jpa\target\jpa-0.0.1-SNAPSHOT_proguard_base.jar] (filtered)
    [INFO] 
    [INFO] --- spring-boot-maven-plugin:2.3.1.RELEASE:repackage (default) @ jpa ---
    [INFO] Replacing main artifact with repackaged archive
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    

    3.4.3 target下文件

    在target目录下会生成5个文件:

    1. jpa-0.0.1-SNAPSHOT.jar混淆后的Spring boot jar,里面包含完整的项目结构,可以运行,这个就是我们本文的产出物;
    2. proguard_map.txt 混淆内容的映射;
    3. proguard_seed.txt 参与混淆的类;
    4. 还有2个未混淆的原始jar包。
     
    target目录生成的文件

    四、 测试jar

    4.1 启动

    命令java -jar jpa-0.0.1-SNAPSHOT.jar启动混淆后的jar,验证是否正常运行。

    D:\dev\GitRepository\jpa\target>java -jar jpa-0.0.1-SNAPSHOT.jar
    
      .   ____          _            __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
     \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.3.0.RELEASE)
    
    2020-07-19 09:12:33.766  INFO 9024 --- [           main] com.erbadagang.data.jpa.JpaApplication   : Starting JpaApplication on guoxiuzhi with PID 9
    024 (D:\dev\GitRepository\jpa\target\jpa-0.0.1-SNAPSHOT.jar started by guoxiuzhi in D:\dev\GitRepository\jpa\target)
    2020-07-19 09:12:33.766  INFO 9024 --- [           main] com.erbadagang.data.jpa.JpaApplication   : No active profile set, falling back to default
    profiles: default
    ......
    

    4.2 请求Controller

    访问URL:http://localhost:8080/user/selectOne?id=5,来测试功能是否正常。

     
    测试Controller

    返回了id=5的梅西相关的数据,证明混合后的代码无问题:

    GET http://localhost:8080/user/selectOne?id=5
    
    HTTP/1.1 200 
    Content-Type: application/json
    Transfer-Encoding: chunked
    Date: Sun, 19 Jul 2020 01:29:24 GMT
    Keep-Alive: timeout=60
    Connection: keep-alive
    
    {
      "id": 5,
      "name": "Messi",
      "age": 24,
      "email": "look@erbadagang.com",
      "createTime": null,
      "updateTime": null,
      "operator": null,
      "deleteFlag": null,
      "version": null
    }
    

    五、混淆效果

    有几次混淆后代码可以正常运行,但是通过反编译工具发现代码根本就没混淆,然后需再调整代码达到混淆的目的,所以需要用反编译工具进行验证是否真的被混淆过。
    java class的反编译工具使用jd-gui。下载地址:http://java-decompiler.github.io/

    原来我是通过解压工具把jar文件解压到文件夹,看一下目录结构后再复制路径到jd-gui进行反编译,其实更便捷的方式是,直接拖动jar文件到jd-gui窗口即可。

    源代码的Service实现类包及类名称:

     
    混淆前的service实现类impl包

    如图:可以看到混淆后service的实现类的包名和类名已经变成了a、b之类的短名称,达到了混淆的效果。
     
    混淆后的核心业务逻辑部分代码——service impl

    底线


    本文源代码使用 Apache License 2.0开源许可协议,可从Gitee代码地址通过git clone命令下载到本地或者通过浏览器方式查看源代码。

     
    链接:https://www.jianshu.com/p/09b0637525db 
  • 相关阅读:
    [BOST] 博赞有机的学习技巧
    [BOST] 你的大脑比你想象的更优秀
    Markdown学习笔记
    nodejs原生态模块,写个聊天室
    【2】自定义WindowsForm分页控件使用【共两篇】
    【1】自定义WindowsForm分页控件使用【共两篇】
    《Log4net写出适合自己的日志类》第三篇【终】【怎样让它适合你自己需求】
    《Log4net写出适合自己的日志类》第二篇【没有理论的实践是盲目】
    《Log4net写出适合自己的日志类》第一篇【上来就是干,先实践后理论】
    记忆留住深刻过往,博客写出平淡事迹【博客首篇】
  • 原文地址:https://www.cnblogs.com/javalinux/p/15674626.html
Copyright © 2020-2023  润新知