美文网首页Java webspringboot
ProGuard代码混淆入门

ProGuard代码混淆入门

作者: 文景大大 | 来源:发表于2021-02-16 09:43 被阅读0次

一、代码混淆的背景

代码的交付一般都是以Jar/War/Ear的形式进行交付的,但是现在有不少工具可以在获得如上的发布包之后进行反编译,使得核心代码逻辑泄露,得不到应有的保护。

  • Jar,Java Archive Resour,指纯Java类的发布包;
  • War,Web Archive Resour,在Jar的基础上还包含了前端静态资源等内容;
  • Ear,Enterprise Archive Resour,在War的基础上还包含了EJB组件等内容;

流行的反编译工具,比如jd-gui可以很方便地对发布包进行反编译,从而破解核心代码逻辑。倘若团队产出的发布包是部署到不受控制的机房的,那么极有可能被潜在的竞争对手获取,造成极大的损失。

二、技术选择

2.1 代码加密

使用加密算法对发布包进行整个的加密,在部署到服务器上的时候,需要配置容器参数和启动参数,并将解密方法也放置在服务器上,使得加密包被解密加载和执行。

这种方案对发布包的保护比较彻底,但是由于解密方法也放在服务器上,所以一旦服务器被攻陷,还是有一定几率导致发布包被解密破解,但是概率小很多,被破解的代价也会很大。

这种方法不是我们今天讨论的主题,因此简要提及即可,对运维能力要求较高,对代码侵入性较低。

2.2 代码混淆

代码一般都是由人写的,那么势必具有可读性,一旦被反编译后,竞争对手可以很快读懂代码逻辑,进行分析和改造。那么我们就需要代码混淆来对反编译后的代码进行可读性的干扰,降低被读懂的概率。

  • ProGuard
  • Allatori

本文先对Proguard进行简单的入门介绍。

三、混淆示例

我们先从start.spring.io上下载一个springboot项目,里面增加一个冒泡排序算法的实现。

@Slf4j
public class BubbleSort {

    public static void bubbleSort(int[] data, int n){
        if(n <= 1){
            log.info("数组中元素少于2个,无需进行排序!");
            return;
        }

        // 最多需要迭代n次冒泡
        for(int i=0;i<n;i++){
            // 表示当前迭代冒泡中是否发生了元素交换
            boolean switchFlag = false;
            for(int j=0;j<n-i-1;j++){
                if(data[j] > data[j+1]){
                    // 不满足从小到大的关系,需要交换
                    int temp = data[j];
                    data[j] = data[j+1];
                    data[j+1] = temp;
                    switchFlag = true;
                }
            }

            // 当前冒泡迭代中没有发生元素交换,说明数列已经有序,完成了排序,可以提前结束
            if(!switchFlag){
                break;
            }
        }
    }

}

其它的pom文件和启动类不做任何改动,此时运行 mvn clean package,就能在项目目录下生成tartget文件夹,找到其中打包好的jar,使用jd-gui打开,就可以看到反编译后的内容为:

未代码混淆之前反编译的效果

代码逻辑被很轻易的破解和复制了。

接下来我们引入ProGuard:

3.2 引入plugin

<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>
                    <proguardVersion>6.2.2</proguardVersion>
                    <injar>${project.build.finalName}.jar</injar>
                    <outjar>${project.build.finalName}.jar</outjar>
                    <obfuscate>true</obfuscate>
                    <libs>
                        <lib>${java.home}/lib/rt.jar</lib>
                        <lib>${java.home}/lib/jce.jar</lib>
                    </libs>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>net.sf.proguard</groupId>
                        <artifactId>proguard-base</artifactId>
                        <version>6.2.2</version>
                    </dependency>
                </dependencies>
</plugin>

3.3 增加配置

配置可以引入外部的文件,也可以直接配置在xml中,我们以后者为例,在<configuration>的最后增加一些配置内容:

<options>
    <option>-target 1.8</option>
    <option>-dontshrink</option>
    <option>-dontoptimize</option>
    <option>-useuniqueclassmembernames</option>
    <option>-adaptclassstrings</option>
    <option>dontusemixedcaseclassnames</option>
    <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod</option>
    <option>-keepclasseswithmembers public class * { public static void main(java.lang.String[]);}</option>
    <option>-keepclassmembers enum * { *; }</option>
</options>

3.4 修改启动类

在启动类中增加内部类定义:

public static class CustomerGenerator implements BeanNameGenerator{
        @Override
        public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
            return beanDefinition.getBeanClassName();
        }
    }

此时,我们就完成了Proguard的入门配置,此时运行 mvn clean package,在target中找到jar,再次使用反编译工具jd-gui,就能看到,代码被混淆了,可读性被降低了。

proguard代码混淆之后反编译的效果

Proguard的官方参考手册如下所示,需要仔细阅读对应的选项内容,然后进行一些适用的配置。

https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/manual/usage.html

本文仅做为入门示例进行记录,后续有时间再对ProGuard进行详细的研究。

相关文章

  • ProGuard代码混淆入门

    一、代码混淆的背景 代码的交付一般都是以Jar/War/Ear的形式进行交付的,但是现在有不少工具可以在获得如上的...

  • ProGuard

    Java代码混淆工具——ProGuard 1.ProGuard简介 简单来说,ProGuard是一个对代码进行压缩...

  • Android使用mapping文件还原混淆代码

    还原混淆文件 ProGuard 提供了命令行来还原混淆后的代码,目录如下: /tools/proguard/bin...

  • java代码混淆工具ProGuard混淆插件

    java代码混淆工具ProGuard混淆插件 介绍 ProGuard是一个纯java编写的混淆工具,有客户端跟ja...

  • Android混淆总结

    Proguard 混淆工具来帮助我们快速地对代码进行混淆。根据 Java 官方介绍,Proguard 对应的具体中...

  • ProGuard代码混淆

    一、简介 ProGuard 工具通过移除无用的代码以及使用语义隐晦的名称来重命名类、字段和方法,从而达到压缩、优化...

  • 代码混淆ProGuard

    1.proguard的四个功能(1).压缩:侦测并移除代码中无用的类、字段、方法和特性。(2).优化:对字节码进行...

  • Proguard代码混淆

    android混淆如果是对android-library那相对比较简单直接在build配置minifyEnable...

  • proguard代码混淆

    springboot项目混淆方案 proguard简单来说是为了防止反编译,更准确的说,进行业务代码的混淆,是使得...

  • proguard代码混淆面试问题讲解

    一、混淆(proguard)到底是什么? ProGuard工具是用于压缩,优化,混淆我们的代码.主作用是可以移除代...

网友评论

    本文标题:ProGuard代码混淆入门

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