J2EE代码混淆
代码混淆    2017-06-23 10:48:08    212    0    0
zejoe   代码混淆

代码混淆:java代码很容易被反编译,泄露重要内容。代码混淆是对编译后生成的内容进行混淆,使反编译后的代码很难被人读懂,但是jvm仍然可以识别。

混淆工具:maven插件proguard-maven-plugin​

使用风险:

  1. 使用spring框架的项目,会对原生代码有依赖,可能会影响运行,但目前的配置已经避免了基本的影响
  2. 混淆后,运行过程中调试代码会比较麻烦,需要对照map文件找到出错位置

使用方法:

  1. 在pom.xml中配置混淆插件proguard-maven-plugin​ 
    <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 http://maven.apache.org/maven-v4_0_0.xsd">
        ……
        <dependencies>
        ……
        </dependencies>
    
        <build>
            <finalName>abc</finalName>
            <plugins>
                <plugin>
                    <groupId>com.github.wvengen</groupId>
                    <artifactId>proguard-maven-plugin</artifactId>
                    <version>2.0.14</version>
                    <executions>
                        <execution>
                            <!--混淆执行的阶段,此处为编译后。可选参数:compile、prepare-package、package-->
                            <phase>process-classes</phase>
                            <goals>
                                <goal>proguard</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <!--混淆后是否打包,默认为true,这里为false-->
                        <attach>false</attach>
                        <obfuscate>true</obfuscate>
                        <!--混淆机制配置文件-->
                        <proguardInclude>${basedir}/proguard.cfg</proguardInclude>
                        <!--仅在attach为true时生效,类似一个后缀,有命名空间的作用-->
                        <!--attachArtifactClassifier>proguard</attachArtifactClassifier-->
                        <!--proguard所依赖的lib-->
                        <libs>
                            <lib>${java.home}/lib/rt.jar</lib>
                        </libs>
                        <!--所混淆文件路径-->
                        <outputDirectory>${project.build.directory}</outputDirectory>
                        <!--所混淆的文件,以混淆文件路径outputDirectory-->
                        <injar>classes</injar>
                        <!--混淆后的输出目录,默认父路径为${project.build.finalName}/WEB-INF/-->
                        <outjar>classes</outjar>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    <!--
    当前配置的混淆过程如下:
    1.在编译生成classs文件后进行混淆:<phase>为process-classes,该配置确保了对编译后生成的target/classes进行混淆
    2.混淆后不打包,直接对classes文件进行混淆。因为混淆生成的war包只有classes文件和配置文件,与一般服务器直接运行的war包目录结构有出入,特别配置的话太麻烦
    3.当前配置执行后,target/classes即为混淆后的classes,正常mvn package打包后生成的war包里的文件即已混淆后的文件
    
    很重要的几个参数:
    <phase> :混淆执行的阶段:compile,process-classes,prepare-package,package
    <attach>:默认为true,指混淆后是否打包,这里如果只想混淆成class文件,则设为false,如果想打包为jar包或者war就设为true
    <outputDirectory>:这个参数容易被误解为混淆后的输出路径,实际指混淆文件的路径,该配置要同<injar>相结合,如果该路径下找不到<injar>配置的文件,则会报错
    <injar>:所混淆的文件,outputDirectory为父路径,参数名容易误解,这里可以配置文件夹,并非只有jar包
    <outjar>:混淆后的输出目录,默认父路径为${project.build.finalName}/WEB-INF/,这才是真正的混淆后的输出目录
    
    未配置的重要参数:
    <attachArtifactType>:在attach为true的情况下才生效,不配置默认为jar,可以配置为war等其他打包格式,但是生成war包后,默认内容只有classes文件和配置文件
    <inFilter>xxx/xxx/abc/**</inFilter>:配置混淆文件的过滤器,除了配置的目录下的文件外,其它文件不被混淆
    -->
     
  2. 混淆机制配置proguard.cfg 
    #通过指定数量的优化能执行
    -optimizationpasses 3
    #混淆时不会产生形形色色的类名
    -dontusemixedcaseclassnames
    #输出生成信息
    -verbose
    #混淆时应用侵入式重载
    -overloadaggressively
    #优化时允许访问并修改有修饰符的类和类的成员
    -allowaccessmodification
    #确定统一的混淆类的成员名称来增加混淆
    -useuniqueclassmembernames
    -target 1.7yi chang
    -ignorewarnings
    -dontshrink
    -dontoptimize
    -dontskipnonpubliclibraryclasses
    -dontskipnonpubliclibraryclassmembers
    
    #---------------分割线以上为默认配置,分割线以下为自定义配置---------------------
    
    #保留以下指定包的包名不被混淆,在spring框架下,某些配置的bean要根据指定路径查找,但是如果包类名有变化就找不到,因此所有spring管理的包名都保留
    -keeppackagenames  xxx.xxx.abc.controller.**
    -keeppackagenames  xxx.xxx.abc.service.**
    -keeppackagenames  xxx.xxx.abc.entity.**
    -keeppackagenames  xxx.xxx.abc.dao.**
    
    #保留以下指定包的成员变量名不被混淆,在spring框架下,某些注入的bean要根据名称映射为类名查找,但是如果注入的成员变量名字变化就找不到,因此所有spring管理的包下的成员变量都保留
    -keepclasseswithmembernames public class xxx.xxx.abc.controller.**
    -keepclasseswithmembernames public class xxx.xxx.abc.service.**
    -keepclasseswithmembernames public class xxx.xxx.abc.entity.**
    -keepclasseswithmembernames public class xxx.xxx.abc.dao.**
    
    #避免混淆泛型,这在JSON实体映射时非常重要
    -keepattributes Signature
    #保护代码中的Annotation不被混淆,这在JSON实体映射时非常重要
    -keepattributes *Annotation*
    #抛出异常时保留代码行号,在异常分析中可以方便定位
    -keepattributes SourceFile,LineNumberTable
    
    #保护所有实体中的字段名称避免数据库生成异常
    -keepclassmembers class * implements java.io.Serializable {
        <fields>
    }
    #保留getset方法,避免spring注入异常
    -keepclassmembers public class * {void set*(***);*** get*();}
     
  3. 混淆结果
    1. 执行mvn package打包后即有混淆结果:
      1. target目录结构:target下增加了几个文件:classes_proguard_base、proguard_map.txt、proguard_seed.txt
      2. classes目录结构:classes文件为编译后的文件,从这里看已经混淆成功,除保护的包名外,其它包名已被混淆
      3. classes_proguard_base:proguard为我们保留了一份编译后混淆前的classes目录
      4. 这是war包解压后的目录,可见混淆后的classes文件已被打入war包
      5. proguard混淆后生成的两个文件:
        1. proguard_map.txt:列出了混淆的映射关系,可以对照映射关系来调试代码
        2. proguard_seed.txt:列出了被保护的类文件即不被混淆的文件

 

网上大多资料有误导,建议参考官方资料,proguard-maven-plugin​洗白说明:

  1. proguard-maven-plugin​可以直接对生成的classes文件进行混淆!
  2. proguard-maven-plugin支持混淆后生成各种类型的包包括war包!

参考链接:

  1. proguard-maven-plugin官方文档
  2. proguard官网
  3. proguard-maven-plugin源码

上一篇: COSBench-OSS Adaptor开发(一)

下一篇: HTTP基本认证,服务器认证客户端(java-python)

212 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航