赞
踩
近期公司的Android项目做了混淆,虽说对于保护代码并不是100%的,但混淆后的代码可以使那些不法份子难以阅读,这样也能对代码的保护做出贡献。
于是,公司写的一大堆WEB项目也想做保护。但几大问题随之而来:
针对以上问题,本人花费一个月研究了WEB+Maven项目的混淆,终于收获果实,解决了这一大空缺难题。
就如之前所述,我们要混淆的项目绝不是一个简单的WEB DEMO,必须要包含了大量第三方框架。
本文中介绍的项目使用了主流的一些框架:
该项目是典型的Maven WEB项目,对于Maven WEB项目的结构不再赘述,这里对各种包做一下解释:
主要混淆对象 对类的名称、属性、方法名都进行混淆
次要混淆对象 对类的名称不混淆,类的属性、方法名选择性混淆
非混淆对象 不进行混淆,混淆后可能出现异常
本文的重头戏,使用Maven集成的ProGuard插件,混淆配置不用单独建立文件
- <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <packaging>war</packaging>
- <groupId>...</groupId>
- <artifactId>zhukun.shiro-spring</artifactId>
- <version>1.0-SNAPSHOT</version>
-
- <!-- 属性-->
- <properties>
- <!-- 项目编码-->
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <!-- 单元测试包-->
- <junit.version>4.12</junit.version>
- <!-- JAVAEE支持包-->
- <jstl.version>1.2</jstl.version>
- <servlet.version>3.1.0</servlet.version>
- <!-- 日志包-->
- <log4j.version>1.2.17</log4j.version>
- <slf4j.version>1.7.10</slf4j.version>
- <aspectj.version>1.6.12</aspectj.version>
- <!-- commons支持-->
- <commons-logging.version>1.1.3</commons-logging.version>
- <commons-collections.version>3.2.1</commons-collections.version>
- <commons-fileupload.version>1.3.1</commons-fileupload.version>
- <!-- shiro安全框架-->
- <shiro.version>1.2.3</shiro.version>
- <!-- druid连接池-->
- <druid.version>1.0.15</druid.version>
- <!-- 数据库及数据库框架-->
- <mysql.version>5.1.30</mysql.version>
- <mybatis.version>3.3.0</mybatis.version>
- <mybatis-spring.version>1.2.3</mybatis-spring.version>
- <!-- Mybatis分页插件-->
- <mybatis-paginator.version>1.2.16</mybatis-paginator.version>
- <!-- Mybatis生成器插件-->
- <mybatis-generator.version>1.3.2</mybatis-generator.version>
- <!-- Spring及SpringMVC支持包-->
- <spring.version>4.1.1.RELEASE</spring.version>
- <jackson.version>2.5.0</jackson.version>
- <!-- 验证码支持包-->
- <patchca.version>1.0.0</patchca.version>
- <!-- Jetty插件-->
- <jetty.version>9.2.7.v20150116</jetty.version>
- <!-- Maven编译插件-->
- <maven-compiler.version>2.3.2</maven-compiler.version>
- </properties>
-
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>${junit.version}</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>jstl</artifactId>
- <version>${jstl.version}</version>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>${log4j.version}</version>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjweaver</artifactId>
- <version>${aspectj.version}</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>${slf4j.version}</version>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>${commons-logging.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-core</artifactId>
- <version>${shiro.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-web</artifactId>
- <version>${shiro.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>${shiro.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-ehcache</artifactId>
- <version>${shiro.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-quartz</artifactId>
- <version>${shiro.version}</version>
- </dependency>
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- <version>${commons-collections.version}</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>${mysql.version}</version>
- </dependency>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>${druid.version}</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>${servlet.version}</version>
- </dependency>
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- <version>${commons-fileupload.version}</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>${mybatis.version}</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>${mybatis-spring.version}</version>
- </dependency>
- <dependency>
- <groupId>com.github.miemiedev</groupId>
- <artifactId>mybatis-paginator</artifactId>
- <version>${mybatis-paginator.version}</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>${jackson.version}</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>${jackson.version}</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>${jackson.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-orm</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- <version>${spring.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.patchca</groupId>
- <artifactId>patchca</artifactId>
- <version>${patchca.version}</version>
- </dependency>
- </dependencies>
-
- <build>
- <finalName>shiro-spring</finalName>
- <!--使Maven打包时能打包src目录下的XML文件-->
- <resources>
- <resource>
- <directory>src/main/java</directory>
- <includes>
- <include>**/*.xml</include>
- </includes>
- </resource>
- <resource>
- <directory>src/main/resources</directory>
- </resource>
- </resources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>${maven-compiler.version}</version>
- <configuration>
- <source>1.7</source>
- <target>1.7</target>
- <encoding>UTF-8</encoding>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
- <version>${jetty.version}</version>
- <configuration>
- <webApp>
- <contextPath>/shiro-spring</contextPath>
- </webApp>
- <httpConnector>
- <!-- 设置端口-->
- <port>8080</port>
- </httpConnector>
- </configuration>
- </plugin>
-
- <!-- MyBatis自动生成Mapper插件-->
- <plugin>
- <groupId>org.mybatis.generator</groupId>
- <artifactId>mybatis-generator-maven-plugin</artifactId>
- <version>${mybatis-generator.version}</version>
- <configuration>
- <verbose>true</verbose>
- <overwrite>true</overwrite>
- </configuration>
- </plugin>
-
- <!-- ProGuard混淆插件-->
- <plugin>
- <groupId>com.github.wvengen</groupId>
- <artifactId>proguard-maven-plugin</artifactId>
- <version>2.0.11</version>
- <executions>
- <execution>
- <!-- 混淆时刻,这里是打包的时候混淆-->
- <phase>package</phase>
- <goals>
- <!-- 使用插件的什么功能,当然是混淆-->
- <goal>proguard</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <!-- 是否将生成的PG文件安装部署-->
- <attach>true</attach>
- <!-- 是否混淆-->
- <obfuscate>true</obfuscate>
- <!-- 指定生成文件分类 -->
- <attachArtifactClassifier>pg</attachArtifactClassifier>
- <options>
- <!-- JDK目标版本1.7-->
- <option>-target 1.7</option>
- <!-- 不做收缩(删除注释、未被引用代码)-->
- <option>-dontshrink</option>
- <!-- 不做优化(变更代码实现逻辑)-->
- <option>-dontoptimize</option>
- <!-- 不路过非公用类文件及成员-->
- <option>-dontskipnonpubliclibraryclasses</option>
- <option>-dontskipnonpubliclibraryclassmembers</option>
- <!-- 优化时允许访问并修改有修饰符的类和类的成员 -->
- <option>-allowaccessmodification</option>
- <!-- 确定统一的混淆类的成员名称来增加混淆-->
- <option>-useuniqueclassmembernames</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>
-
- <!-- 不混淆job包下的所有类名,且类中的方法也不混淆-->
- <option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.job.** { <methods>; }</option>
- <!-- 不混淆filter包下的所有类名,这里主要是对Shiro的路踢人过滤器混淆,对类的属性和方法进行了混淆-->
- <option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.filter.** </option>
- <!-- 不混淆凭证包下的所有类名,但对类中的属性、方法进行混淆,原因是Spring配置中用到了这个类名-->
- <option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.credntials.** </option>
- <!-- 混淆目的同上,这个是拦截器的包,包中有防止重复提交的拦截器-->
- <option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.interceptor.** </option>
- <!-- 混淆目的同上,这个是域包,包中有用户登录域-->
- <option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.realm.** </option>
- <!-- 不混淆model包中的所有类以及类的属性及方法,实体包,混淆了会导致ORM框架及前端无法识别-->
- <option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.model.** {*;}</option>
- <!-- 以下两个包因为大部分是Spring管理的Bean,不对包类的类名进行混淆,但对类中的属性和方法混淆-->
- <option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.service.** </option>
- <option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.dao.**</option>
- </options>
- <outjar>${project.build.finalName}-pg.jar</outjar>
- <!-- 添加依赖,这里你可以按你的需要修改,这里测试只需要一个JRE的Runtime包就行了 -->
- <libs>
- <lib>${java.home}/lib/rt.jar</lib>
- </libs>
- <!-- 加载文件的过滤器,就是你的工程目录了-->
- <inFilter>com/chinatelecom/gz/wy/zhukun/shiro_spring/**</inFilter>
- <!-- 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧-->
- <injar>classes</injar>
- <!-- 输出目录-->
- <outputDirectory>${project.build.directory}</outputDirectory>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </project>
以上代码中的注释足够各位参考了,若有问题欢迎留言
clean package -DskipTests
使用Maven运行以上代码,执行完成后在target目录中会生成三个文件:
混淆完成后,将classes-pg.jar解压到应用服务器覆盖原有的classes文件,通常目录为
X:\jetty9或tomcat7\webapps\shiro-spring\WEB-INF\classes
运行服务,项目运行正常
既然是混淆了的代码,那我们现在作为盗码者来反编译一下classes文件
可以看出,混淆成功了,盗码者读起来不是一二般的痛苦,我们的目的已经达到
欢迎大家讨论更加的代码保护方案,代码是我们辛苦的成果,绝不让他人非法盗取。当然,本文在非本人的同意下也禁止盗用,转载的话说明出处,谢谢合作!
注:本文中提到的项目源码为商业机密,恕不提供,谢谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。