美文网首页
proguard代码混淆

proguard代码混淆

作者: 虾米咬小米 | 来源:发表于2020-08-12 17:02 被阅读0次

    springboot项目混淆方案

    proguard简单来说是为了防止反编译,更准确的说,进行业务代码的混淆,是使得代码易读性变差。
    引入proguard-maven-plugin
    一:

    <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>
              <proguardVersion>6.0.3</proguardVersion>
              <injar>${project.build.finalName}.jar</injar>
              
              <outjar>${project.build.finalName}.jar</outjar>
              
                        <outjar>${project.build.finalName}.jar</outjar>
              -->
              <obfuscate>true</obfuscate>
              <options>
                <!--# JDK目标版本1.8-->
                <option>-target 1.8</option>
                <!-- 不做收缩(删除注释、未被引用代码)-->
                <option>-dontshrink</option>
                <!-- 不做优化(变更代码实现逻辑)-->
                <option>-dontoptimize</option>
                <!--  ##对于类成员的命名的混淆采取唯一策略-->
                <option>-useuniqueclassmembernames</option>
                <!--## 混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代-->
                <option>-adaptclassstrings</option>
                <!--混淆时不生成大小写混合的类名,默认是可以大小写混合-->
                <option>-dontusemixedcaseclassnames</option>
                <!--忽略警告-->
                <option>-ignorewarnings</option>
                <!-- This option will replace all strings in reflections method invocations with new class names.
                     For example, invokes Class.forName('className')-->
                <!-- <option>-adaptclassstrings</option> -->
                <!-- This option will save all original annotations and etc. Otherwise all we be removed from files.-->
                <!-- 不混淆所有特殊的类-->
                <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                  SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
                </option>
                <!-- This option will save all original names in interfaces (without obfuscate).-->
                <!--
                             <option>-keepnames interface **</option>
                -->
                <!-- This option will save all original methods parameters in files defined in -keep sections,
                     otherwise all parameter names will be obfuscate.-->
    
                <!--保留参数名字-->
                <option>-keepparameternames</option>
                <!--保留主进程入口-->
                <!--
                            <option>-keep @org.springframework.boot.autoconfigure.SpringBootApplication class * {*;}</option>
                -->
                <!-- <option>-libraryjars **</option> -->
                <!-- This option will save all original class files (without obfuscate) but obfuscate all in domain package.-->
                <!--<option>-keep class !com.slm.proguard.example.spring.boot.domain.** { *; }</option>-->
    
    <!--
                <option>-keep class !com.bmsoft.graph.** { *; }</option>
    -->
                <option>-keep class com.bmsoft.graph.config.** { *; }</option>
                <option>-keep class com.bmsoft.graph.LinkGraphApplication { *; }</option>
                <option>-keep class com.bmsoft.graph.mapper.** { *; }</option>
    <!--
                <option>-keep class com.bmsoft.graph.auth.filter.** { *; }</option>
    -->
                <option>-keep class com.bmsoft.graph.aspect.** { *; }</option>
                <option>-keep class com.bmsoft.graph.domain.** { *; }</option>
                <option>-keep class com.bmsoft.graph.controller.** { *; }</option>
    <!--
                <option>-keep interface * extends * { *; }</option>
    -->
                 <!--##保留枚举成员及方法-->
                <option> -keepclassmembers enum * { *; }</option>
                <option>-keepclassmembers class * {
                  <!-- @org.springframework.beans.factory.annotation.Autowired *; -->
                  @org.springframework.beans.factory.annotation.Autowired *;
                  @org.springframework.beans.factory.annotation.Value *;
                  }
                </option>
              </options>
              <libs>
                <!-- Include main JAVA library required.-->
                <lib>${java.home}/lib/rt.jar</lib>
                <lib>${java.home}/lib/jce.jar</lib>
                <!-- <lib>${java.home}/lib/spring-boot-starter-web-1.4.1.RELEASE.jar</lib> -->
              </libs>
            </configuration>
            <dependencies>
              <dependency>
                <groupId>net.sf.proguard</groupId>
                <artifactId>proguard-base</artifactId>
                <version>6.0.3</version>
              </dependency>
            </dependencies>
          </plugin>
    

    这里引用了com.github.wvengen的proguard-maven-plugin插件,使用的proguard-base版本是6.0.3
    这里使用java8,因为libs那里照常配置rt.jar,jce.jar,如果是java9的话,则需要换成相应的模块。

    另外指定proguard的阶段为package,springboot打包在repackage阶段

    <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
              <execution>
                <!-- <phase>none</phase> -->
                <goals>
                  <goal>repackage</goal>
                </goals>
                <configuration>
                  <mainClass>com.bmsoft.graph.LinkGraphApplication</mainClass>
                </configuration>
              </execution>
            </executions>
          </plugin>
    

    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]  with existing, non-compatible bean definition of same name and class [com.example.demo.b.a]
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:181) ~[spring-context-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
    

    需要在更改bean 命名:

    public class LinkGraphApplication {
    
      public static class CustomGenerator implements BeanNameGenerator {
    
        @Override
        public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
          return definition.getBeanClassName();
        }
      }
    
      public static void main(String[] args) {
        new SpringApplicationBuilder(LinkGraphApplication.class)
            .beanNameGenerator(new CustomGenerator())
            .run(args);
      }
    }
    

    运行jar包
    nohup java -jar jar包名.jar -&

    可能出现的问题

    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'springfox.documentation.spring.web.scanners.ApiListingScanner' defined in URL 
    

    项目中引入了swagger 插件,需要在打包的时候,不进行bean的初始化配置@ConditionalOnProperty()

    @Configuration
    @ConditionalOnProperty(prefix = "swagger", value = {"enable"}, havingValue = "true")
    @EnableSwagger2
    public class SwaggerConfig {
    }
    

    注意
    -keep class 类/包.** 表示保留类名

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

    参考:
    springboot项目混淆方案

    由于需要将源码打包做代码混淆,选择proguard,开始使用各种问题,各种jar包版本问题,但最终成功了,记录一下,也希望能够帮助大家

    在pom中添加代码:

    <build>
            <finalName>${artifactId}</finalName>
            <plugins>
                <plugin>
                    <groupId>com.github.wvengen</groupId>
                    <artifactId>proguard-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals><goal>proguard</goal></goals>
                        </execution>
                    </executions>
                    <configuration>
                        <proguardVersion>6.0.3</proguardVersion>
                        <injar>${project.build.finalName}.jar</injar>
                        <!-- <injar>classes</injar> -->
                        <outjar>${project.build.finalName}.jar</outjar>
                        <obfuscate>true</obfuscate>
                        <options>
                            <!-- 不做收缩(删除注释、未被引用代码)-->
                            <option>-dontshrink</option>
                            <!-- 不做优化(变更代码实现逻辑)-->
                            <option>-dontoptimize</option>
                            <!-- This option will replace all strings in reflections method invocations with new class names.
                                 For example, invokes Class.forName('className')-->
                            <!-- <option>-adaptclassstrings</option> -->
                            <!-- This option will save all original annotations and etc. Otherwise all we be removed from files.-->
                            <!-- 不混淆所有特殊的类-->
                            <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod</option>
                            <!-- This option will save all original names in interfaces (without obfuscate).-->
                            <option>-keepnames interface **</option>
                            <!-- This option will save all original methods parameters in files defined in -keep sections,
                                 otherwise all parameter names will be obfuscate.-->
                            <option>-keepparameternames</option>
                            <!-- <option>-libraryjars **</option> -->
                            <!-- This option will save all original class files (without obfuscate) but obfuscate all in domain package.-->
                            <!--<option>-keep class !com.slm.proguard.example.spring.boot.domain.** { *; }</option>-->
                            <option>-keep class !com.ts.** { *; }</option>
                            <option>-keep class com.ts.Application { *; }</option>
                            <option>-keep class com.ts.SwaggerConfig { *; }</option>
                            <option>-keep class com.ts.common.** { *; }</option>
                            <option>-keep class com.ts.aop.** { *; }</option>
                            <option>-keep class com.ts.config.** { *; }</option>
                            <option>-keep class com.ts.sunshine.controller.** { *; }</option>
                            <!-- This option will save all original class files (without obfuscate) in service package-->
                            <!--<option>-keep class com.slm.proguard.example.spring.boot.service { *; }</option>-->
                            <!-- This option will save all original interfaces files (without obfuscate) in all packages.-->
                            <option>-keep interface * extends * { *; }</option>
                            <!-- <option>-keep @org.springframework.stereotype.Service class *</option> -->
                            <!-- This option will save all original defined annotations in all class in all packages.-->
                            <option>-keepclassmembers class * {
                                    <!-- @org.springframework.beans.factory.annotation.Autowired *; -->
                                    @org.springframework.beans.factory.annotation.Value *;
                                }
                            </option>
                        </options>
                        <libs>
                            <!-- Include main JAVA library required.-->
                            <lib>${java.home}/lib/rt.jar</lib>
                            <!-- <lib>${java.home}/lib/spring-boot-starter-web-1.4.1.RELEASE.jar</lib> -->
                        </libs>
                    </configuration>
                    <dependencies>
                        <dependency>
                            <groupId>net.sf.proguard</groupId>
                            <artifactId>proguard-base</artifactId>
                            <version>6.0.3</version>
                        </dependency>
                    </dependencies>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <!-- <phase>none</phase> -->
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                            <configuration>
                                <mainClass>com.ts.Application</mainClass>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    

    注意:

    -keep class 类/包.** 表示保留类名

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

    参考:

    springboot2.x+maven+proguard代码混淆

    ProGuard代码混淆详细攻略

    相关文章

      网友评论

          本文标题:proguard代码混淆

          本文链接:https://www.haomeiwen.com/subject/urdmdktx.html