Skip to content

Commit a3f900b

Browse files
committed
代码授权码加密与混淆demo
1 parent 8404021 commit a3f900b

25 files changed

+1903
-6
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,3 +619,7 @@
619619
/springboot-unit-resp/target/classes/com/github/lybgeek/user/service/impl/UserServiceImpl.class
620620
/springboot-unit-resp/target/classes/com/github/lybgeek/user/service/UserService.class
621621
/springboot-unit-resp/target/generated-sources/annotations/com/github/lybgeek/user/convert/UserConvertImpl.java
622+
/springboot-code-authorization/target/classes/
623+
/springboot-code-authorization/springboot-code-authorization.iml
624+
/springboot-mybatis-autoId/target/
625+
/springboot-mybatis-autoId/springboot-mybatis-autoId.iml

pom.xml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<module>springboot-mq-idempotent-consume</module>
3333
<module>springboot-unit-resp</module>
3434
<module>springboot-mybatis-autoId</module>
35+
<module>springboot-code-authorization</module>
3536
</modules>
3637
<parent>
3738
<groupId>org.springframework.boot</groupId>
@@ -467,12 +468,6 @@
467468
<artifactId>spring-boot-starter-web</artifactId>
468469
</dependency>
469470

470-
<dependency>
471-
<groupId>org.springframework.boot</groupId>
472-
<artifactId>spring-boot-devtools</artifactId>
473-
<scope>runtime</scope>
474-
<optional>true</optional>
475-
</dependency>
476471
<dependency>
477472
<groupId>org.projectlombok</groupId>
478473
<artifactId>lombok</artifactId>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
该demo主要演示通过自定类加载器来实现代码加密,以及通过proguard插件来实现混淆加密,并把自定义加载器加载的类与spring进行整合
1.32 KB
Binary file not shown.
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>springboot-learning</artifactId>
7+
<groupId>com.github.lybgeek</groupId>
8+
<version>0.0.1-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>springboot-code-authorization</artifactId>
13+
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>org.springframework.boot</groupId>
18+
<artifactId>spring-boot-starter-web</artifactId>
19+
</dependency>
20+
21+
<dependency>
22+
<groupId>org.springframework.boot</groupId>
23+
<artifactId>spring-boot-starter-freemarker</artifactId>
24+
</dependency>
25+
<dependency>
26+
<groupId>com.baomidou</groupId>
27+
<artifactId>mybatis-plus-boot-starter</artifactId>
28+
</dependency>
29+
<dependency>
30+
<groupId>com.baomidou</groupId>
31+
<artifactId>mybatis-plus-generator</artifactId>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.yaml</groupId>
35+
<artifactId>snakeyaml</artifactId>
36+
</dependency>
37+
<dependency>
38+
<groupId>com.alibaba</groupId>
39+
<artifactId>druid-spring-boot-starter</artifactId>
40+
</dependency>
41+
42+
<dependency>
43+
<groupId>org.springframework.boot</groupId>
44+
<artifactId>spring-boot-starter-aop</artifactId>
45+
</dependency>
46+
47+
<dependency>
48+
<groupId>cglib</groupId>
49+
<artifactId>cglib</artifactId>
50+
</dependency>
51+
52+
<dependency>
53+
<groupId>mysql</groupId>
54+
<artifactId>mysql-connector-java</artifactId>
55+
<scope>runtime</scope>
56+
</dependency>
57+
<dependency>
58+
<groupId>org.springframework.boot</groupId>
59+
<artifactId>spring-boot-configuration-processor</artifactId>
60+
<optional>true</optional>
61+
</dependency>
62+
<dependency>
63+
<groupId>org.springframework.boot</groupId>
64+
<artifactId>spring-boot-starter-test</artifactId>
65+
<scope>test</scope>
66+
</dependency>
67+
68+
<dependency>
69+
<groupId>org.apache.commons</groupId>
70+
<artifactId>commons-lang3</artifactId>
71+
</dependency>
72+
<dependency>
73+
<groupId>org.mybatis.spring.boot</groupId>
74+
<artifactId>mybatis-spring-boot-starter</artifactId>
75+
</dependency>
76+
77+
</dependencies>
78+
79+
<build>
80+
<plugins>
81+
<plugin>
82+
<groupId>org.springframework.boot</groupId>
83+
<artifactId>spring-boot-maven-plugin</artifactId>
84+
</plugin>
85+
86+
<plugin>
87+
<groupId>com.github.wvengen</groupId>
88+
<artifactId>proguard-maven-plugin</artifactId>
89+
<version>2.0.14</version>
90+
<executions>
91+
<execution>
92+
<!-- 混淆时刻,这里是打包的时候混淆-->
93+
<phase>package</phase>
94+
<goals>
95+
<!-- 使用插件的什么功能: 混淆-->
96+
<goal>proguard</goal>
97+
</goals>
98+
</execution>
99+
</executions>
100+
<configuration>
101+
<proguardVersion>6.0.2</proguardVersion>
102+
<!-- 是否将生成的PG文件安装部署-->
103+
<attach>true</attach>
104+
<!-- 是否混淆-->
105+
<obfuscate>true</obfuscate>
106+
<!-- 指定生成文件分类 -->
107+
<attachArtifactClassifier>pg</attachArtifactClassifier>
108+
<options>
109+
<!-- JDK目标版本1.8-->
110+
<option>-target 1.8</option>
111+
<!-- 不做收缩(删除注释、未被引用代码)-->
112+
<option>-dontshrink</option>
113+
<!-- 不做优化(变更代码实现逻辑)-->
114+
<option>-dontoptimize</option>
115+
<!-- 不路过非公用类文件及成员-->
116+
<option>-dontskipnonpubliclibraryclasses</option>
117+
<option>-dontskipnonpubliclibraryclassmembers</option>
118+
<!-- 优化时允许访问并修改有修饰符的类和类的成员 -->
119+
<option>-allowaccessmodification</option>
120+
<!-- 确定统一的混淆类的成员名称来增加混淆-->
121+
<option>-useuniqueclassmembernames</option>
122+
123+
<!--保证spring注解能力-->
124+
<option>-keepdirectories</option>
125+
126+
<!-- 不混淆所有包名,本人测试混淆后WEB项目问题实在太多,毕竟Spring配置中有大量固定写法的包名-->
127+
<option>-keeppackagenames</option>
128+
<!-- 不混淆所有特殊的类-->
129+
<option>-keepattributes
130+
Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
131+
</option>
132+
<!-- 不混淆所有的set/get方法,毕竟项目中使用的部分第三方框架(例如Shiro)会用到大量的set/get映射-->
133+
<option>-keepclassmembers public class * {void set*(***);*** get*();}</option>
134+
135+
<option>-keep class com.github.lybgeek.user.**.entity.** {*;}</option>
136+
<option>-keep class com.fuse.cdn.api.modules.**.dto.** {*;}</option>
137+
138+
139+
<!-- 以下包因为大部分是Spring管理的Bean,不对包类的类名进行混淆,但对类中的属性和方法混淆-->
140+
<option>-keep class com.github.lybgeek.user.**.controller.**</option>
141+
<option>-keep class com.github.lybgeek.user.**.service.**</option>
142+
<option>-keep class ccom.github.lybgeek.user.**.dao.**{*;}</option>
143+
144+
145+
<!-- 不混淆启动类,否则spring-boot不能正常启动 -->
146+
<option>-keep class com.github.lybgeek.CodeAuthorizationApplication</option>
147+
148+
<!-- 忽略打包时的告警信息 -->
149+
<option>-ignorewarnings</option>
150+
151+
</options>
152+
<outjar>${project.build.finalName}</outjar>
153+
<!-- 添加依赖,这里你可以按你的需要修改,这里测试只需要一个JRE的Runtime包就行了 -->
154+
<libs>
155+
<lib>${java.home}/lib/rt.jar</lib>
156+
<lib>${java.home}/lib/jce.jar</lib>
157+
</libs>
158+
<outputDirectory>${project.build.directory}</outputDirectory>
159+
</configuration>
160+
<dependencies>
161+
<dependency>
162+
<groupId>net.sf.proguard</groupId>
163+
<artifactId>proguard-base</artifactId>
164+
<version>6.0.2</version>
165+
<scope>runtime</scope>
166+
</dependency>
167+
</dependencies>
168+
</plugin>
169+
</plugins>
170+
</build>
171+
172+
173+
</project>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.github.lybgeek;
2+
3+
4+
import org.mybatis.spring.annotation.MapperScan;
5+
import org.springframework.boot.SpringApplication;
6+
import org.springframework.boot.autoconfigure.SpringBootApplication;
7+
8+
@SpringBootApplication
9+
@MapperScan(basePackages = "com.github.lybgeek.**.dao")
10+
public class CodeAuthorizationApplication {
11+
12+
13+
public static void main(String[] args) {
14+
SpringApplication.run(CodeAuthorizationApplication.class, args);
15+
}
16+
17+
18+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.github.lybgeek.common.classloader;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.apache.commons.lang3.StringUtils;
5+
6+
import java.io.ByteArrayOutputStream;
7+
import java.io.FileInputStream;
8+
import java.io.IOException;
9+
import java.io.InputStream;
10+
11+
@Slf4j
12+
public class CustomClassLoader extends ClassLoader{
13+
14+
/**
15+
* 授权码
16+
*/
17+
private String secretKey;
18+
19+
private String SECRETKEY_PREFIX = "lyb-geek";
20+
21+
22+
/**
23+
* class文件的根目录
24+
*/
25+
private String classRootDir = "META-INF/services/";
26+
27+
public CustomClassLoader(String secretKey) {
28+
this.secretKey = secretKey;
29+
}
30+
31+
32+
public String getClassRootDir() {
33+
return classRootDir;
34+
}
35+
36+
public void setClassRootDir(String classRootDir) {
37+
this.classRootDir = classRootDir;
38+
}
39+
40+
@Override
41+
protected Class<?> findClass(String name) throws ClassNotFoundException {
42+
43+
Class<?> clz = findLoadedClass(name);
44+
//先查询有没有加载过这个类。如果已经加载,则直接返回加载好的类。如果没有,则加载新的类。
45+
if(clz != null){
46+
return clz;
47+
}else{
48+
ClassLoader parent = this.getParent();
49+
clz = getaClass(name, clz, parent);
50+
51+
if(clz != null){
52+
return clz;
53+
}else{
54+
clz = getaClass(name);
55+
}
56+
57+
}
58+
59+
return clz;
60+
61+
}
62+
63+
private Class<?> getaClass(String name) throws ClassNotFoundException {
64+
Class<?> clz;
65+
byte[] classData = getClassData(name);
66+
if(classData == null){
67+
throw new ClassNotFoundException();
68+
}else{
69+
clz = defineClass(name, classData, 0,classData.length);
70+
}
71+
return clz;
72+
}
73+
74+
private Class<?> getaClass(String name, Class<?> clz, ClassLoader parent) {
75+
try {
76+
//委派给父类加载
77+
clz = parent.loadClass(name);
78+
} catch (Exception e) {
79+
//log.warn("parent load class fail:"+ e.getMessage(),e);
80+
}
81+
return clz;
82+
}
83+
84+
private byte[] getClassData(String classname){
85+
if(StringUtils.isEmpty(secretKey) || !secretKey.contains(SECRETKEY_PREFIX) || secretKey.split(SECRETKEY_PREFIX).length != 2){
86+
throw new RuntimeException("secretKey is illegal");
87+
}
88+
String path = CustomClassLoader.class.getClassLoader().getResource("META-INF/services/").getPath() +"/"+ classname+".lyb";
89+
InputStream is = null;
90+
ByteArrayOutputStream bas = null;
91+
try{
92+
is = new FileInputStream(path);
93+
bas = new ByteArrayOutputStream();
94+
int len;
95+
//解密
96+
String[] arrs = secretKey.split(SECRETKEY_PREFIX);
97+
long key = Long.valueOf(arrs[1]);
98+
// System.out.println("key:"+key);
99+
while((len = is.read())!=-1){
100+
byte data = (byte)(len - key - secretKey.length());
101+
bas.write(data);
102+
}
103+
return bas.toByteArray();
104+
}catch(Exception e){
105+
e.printStackTrace();
106+
return null;
107+
}finally{
108+
try {
109+
if(is!=null){
110+
is.close();
111+
}
112+
} catch (IOException e) {
113+
log.error("encrypt fail:"+e.getMessage(),e);
114+
}
115+
try {
116+
if(bas!=null){
117+
bas.close();
118+
}
119+
} catch (IOException e) {
120+
e.printStackTrace();
121+
}
122+
}
123+
124+
}
125+
126+
127+
}

0 commit comments

Comments
 (0)