0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

java中的代码混淆技术

科技绿洲 来源:了不起 作者:了不起 2023-09-25 11:48 次阅读

今天和大家一起学习下java中的代码混淆技术,后面你也可以让你的代码不再裸露在外了,让人轻易窥视

代码混淆技术

当需要阅读jar文件的内容时,可能你会使用一些反编译工具,比如jd-gui,但是否有遇到反编译后的内容和想象的不一样,但正常引用该jar又都是正常的?

开始的话

前段时间,使用了docx4j的库来操作.docx文件进行一些复杂的操作,比如对多个docx文件进行合并,在网上找了很多的方式发现最终生成的文档都有很多多余的内容, 导致原本几兆的文件合并后有几十兆,记得docx4j官网有提供商业版本的方法,准备窥探下其源码来研究下,然而当我下载好jar后打开时,我蒙了...

图片

简介

我们知道,一般情况下编译打包后的jar文件可以通过反编译工具看到jar中的接口、类、方法都是可以被,这样相关的代码实现很容易被模仿借鉴,企业的核心代码很可能被人盗用。特别是一些涉密较强或者商业性的行业软件,当被拿到jar并反编译后如同开源一般。那么通过对class文件进行字节码级别的混淆加密,就能够在一定程度防止技术被模仿或复用, 从而对java软件起到很好的保护作用。

实现方式

  1. 对class文件进行加密,但是需要特定的Classloader在加载class时对其解密
  2. 针对class文件反编译原理,通过花指令防止文件被反编译
  3. 基于代码混淆技术,对代码中的包、类、方法等名称进行混淆,从而提高代码阅读成本

示例

今天主要介绍通过第3种方法实现代码混淆,这里主要使用了proguard工具对应的maven插件 proguard-maven-plugin :

Proguard是一个Java类文件压缩器、优化器、混淆器、预校验器。压缩环节会检测以及移除没有用到的类、字段、方法以及属性。优化环节会分析以及优化方法的字节码。混淆环节会用无意义的短变量去重命名类、变量、方法。这些步骤让代码更精简,更高效,也更难被逆向(破解)

比如我们基于Restful开发一个用户服务接口

  1. 可能你的项目结构会是这样的:
packages...
├ entity
|  ├ User
├ dao
|  ├ UserDao
|  ├ impl
|    ├ UserDaoImpl
├ service
|  ├ UserService
|  ├ impl
|    ├ UserServiceImpl
├ web
|  ├ UserController

通过命令mvn package打包后,结构是这样的:

图片

  1. 现在引入proguard:

需要在pom.xml中build标签中加入插件,具体配置如下:

< !-- ProGuard混淆插件-- >
            < plugin >
                < groupId >com.github.wvengen< /groupId >
                < artifactId >proguard-maven-plugin< /artifactId >
                < version >2.6.0< /version >
                < executions >
                    < execution >
                        < !-- 混淆时刻,这里是打包的时候混淆-- >
                        < phase >package< /phase >
                        < goals >
                            < !-- 使用插件的什么功能-- >
                            < goal >proguard< /goal >
                        < /goals >
                    < /execution >
                < /executions >
                < configuration >
                    < !-- 是否将生成的PG文件安装部署-- >
                    < attach >true< /attach >
                    < !-- 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧-- >
                    < injar >${project.build.finalName}.jar< /injar >
                    < !--class 混淆后输出的jar包-- >
                    < outjar >${project.build.finalName}-pg.jar< /outjar >
                    < !-- 是否混淆-- >
                    < obfuscate >true< /obfuscate >
                    < !-- 配置一个文件,通常叫做proguard.cfg,该文件主要是配置options选项,也就是说使用proguard.cfg那么options下的所有内容都可以移到proguard.cfg中 -- >
                    < proguardInclude >${project.basedir}/proguard.cfg< /proguardInclude >
                    < !-- 指定生成文件分类 -- >
                    < attachArtifactClassifier >pg< /attachArtifactClassifier >
                    < !-- 额外的jar包,通常是项目编译所需要的jar -- >
                    < libs >
                        < lib >${java.home}/lib/rt.jar< /lib >
                    < /libs >
                    < !-- 对输入jar进行过滤比如,如下配置就是对META-INFO文件不处理。 -- >
                    < inLibsFilter >!META-INF/**< /inLibsFilter >
                    < !-- 这是输出路径配置,但是要注意这个路径必须要包括injar标签填写的jar -- >
                    < outputDirectory >${project.basedir}/target< /outputDirectory >
                    < !--这里特别重要,此处主要是配置混淆的一些细节选项,比如哪些类不需要混淆,哪些需要混淆-- >
                    < options >
                        < !-- 可以在此处写option标签配置,不过我上面使用了proguardInclude,故而我更喜欢在proguard.cfg中配置 -- >
                    < /options >
                < /configuration >
            < /plugin >

其中配置文件proguard.cfg如下:

#指定Java的版本
-target 1.8
#proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等
-dontshrink
#是否关闭字节码级别的优化,如果不开启则设置如下配置
-dontoptimize
#混淆时不生成大小写混合的类名,默认是可以大小写混合
-dontusemixedcaseclassnames
# 对于类成员的命名的混淆采取唯一策略
-useuniqueclassmembernames
#混淆时不生成大小写混合的类名,默认是可以大小写混合
-dontusemixedcaseclassnames
#混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代
-adaptclassstrings
 
#对异常、注解信息予以保留
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
# 此选项将保存接口中的所有原始名称(不混淆)-- >
# -keepnames interface ** { *; }
# 此选项将保存所有软件包中的所有原始接口文件(不进行混淆)
#-keep interface * extends * { *; }
#保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数
-keepparameternames
# 保留枚举成员及方法
-keepclassmembers enum * { *; }
# 不混淆所有类,保存原始定义的注释-
-keepclassmembers class * {
                        @org.springframework.context.annotation.Bean *;
                        @org.springframework.beans.factory.annotation.Autowired *;
                        @org.springframework.beans.factory.annotation.Value *;
                        @org.springframework.stereotype.Service *;
                        @org.springframework.stereotype.Component *;
                        }
 
#忽略warn消息
-ignorewarnings
#忽略note消息
-dontnote
#打印配置信息
-printconfiguration
  1. 执行打包命令mvc package,可以看到target目录下新增了几个文件
  • obfuscation-pg.jar 混淆处理后的输出jar
  • proguard_map.txt 存放混淆前后类、方法的对应关系
  • proguard_seed.txt 存放保持不变的类 可见包的名称、类名都改成了短字母

图片

实现技术

通过proguard来实现class内容的混淆相对比较简单,当然还有很多其他的技术方法,比如上面说到的对class进行加密这种更安全的技术手段,感兴趣的你可以继续探究。

其他技术

  • Jocky
  • retroguard
  • androidkiller
  • ClassFinal

结束语

此篇文章简单介绍了java中的代码混淆技术,我们可以根据具体的项目需求对编译后的代码进行混淆或加密处理,从而保护自己的劳动成果。开头看到的docx4j企业级功能提供 的jar具体是怎么实现代码保护的,目前还没发现其具体采用了什么技术实现,后面继续研究。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2956

    浏览量

    104530
  • 开源
    +关注

    关注

    3

    文章

    3243

    浏览量

    42378
  • 源码
    +关注

    关注

    8

    文章

    633

    浏览量

    29134
  • 代码
    +关注

    关注

    30

    文章

    4741

    浏览量

    68323
  • 编译
    +关注

    关注

    0

    文章

    652

    浏览量

    32800
收藏 人收藏

    评论

    相关推荐

    如何通过注解来优化我们的Java代码

    注解? Java注解是一种元数据形式,可以被添加到Java代码的各种元素(类、方法、字段等)上,以提供关于这些元素的额外信息。注解是在Java
    的头像 发表于 09-30 11:39 592次阅读

    详解java代码优化方法

    Java代码优化是Java编程开发很重要的一个步骤,Java代码优化要注重细节优化,一个两个的细节的优化,产生的效果不大,但是如果处处都能注
    发表于 04-02 15:43

    Java程序设计经典教程(源代码)

    Java程序设计经典教程(源代码): 基于swing的Java可视化软件开发在代码编辑区中生成如下所示程序框架代码:package pack
    发表于 12-08 17:37 87次下载

    工程制图网络习题系统JAVA 应用

    本文主要介绍基于AUTOCAD 二次开发的工程制图习题系统JAVA 技术的应用,主要涉及到JAVA 对非JAVA
    发表于 09-02 15:40 5次下载

    JAVA版聊天软件源代码

    JAVA版聊天软件源代码 一款用JAVA制作开发的小型聊天软件,里面附有安装程序和JAVA代码。.rar
    发表于 03-11 14:21 0次下载

    贪吃蛇游戏java代码

    贪吃蛇游戏java代码
    发表于 12-27 17:56 9次下载

    统计java代码行数和jar包.class代码的行数

    本文档内容介绍了统计java代码行数和jar包.class代码的行数,供参考
    发表于 03-19 15:27 0次下载

    代码保护之道——混淆的艺术

    第三点是藏叶于林。安全是业务的天然属性,业务是安全的最佳载体。只有结合了业务的安全才是真正的安全,孤立的安全是很容易被攻击者攻破的。将业务代码和安全代码放在一起进行混淆,攻击者要破解的话,不但要摸清安全逻辑,还要了解清楚整个业务
    的头像 发表于 12-13 11:11 4738次阅读
    <b class='flag-5'>代码</b>保护之道——<b class='flag-5'>混淆</b>的艺术

    Java异常的习题和代码分析

    Java异常的习题和代码分析
    发表于 07-08 14:54 5次下载
    <b class='flag-5'>Java</b>异常的习题和<b class='flag-5'>代码</b>分析

    Java的iterator和foreach遍历集合源代码

    Java的iterator和foreach遍历集合源代码
    发表于 03-17 09:16 9次下载
    <b class='flag-5'>Java</b>的iterator和foreach遍历集合源<b class='flag-5'>代码</b>

    如何在java代码中使用HTTP代理IP

    如何在java代码中使用HTTP代理IP。
    的头像 发表于 08-04 15:38 2186次阅读

    Java反编译反混淆编程实例分析

    支持对已混淆的ja (1).控制台输出(没有反混淆)r包进行反混淆
    发表于 06-01 14:48 1466次阅读
    <b class='flag-5'>Java</b>反编译反<b class='flag-5'>混淆</b>编程实例分析

    APP混淆实战(Java/so代码混淆)

    Android App Bundle混淆加密加壳加固保护的解决方案(过Google App上架审核)最全Android及资源混淆方法汇总(无需加固节约成本并将APP上架Google Play成功的最佳方案)
    的头像 发表于 06-29 15:42 872次阅读
    APP<b class='flag-5'>混淆</b>实战(<b class='flag-5'>Java</b>/so<b class='flag-5'>代码</b><b class='flag-5'>混淆</b>)

    用了Stream后,代码反而越写越丑?

    Java,同样的功能,代码行数写的少了,并不见得你的代码就好。由于Java使用;作为代码行的
    的头像 发表于 08-23 15:08 444次阅读

    java反编译的代码可以修改么

    Java反编译是一种将编译后的Java字节码(.class文件)转换回源代码的过程。反编译后的代码可以进行修改,但是需要注意,反编译代码的质
    的头像 发表于 09-02 11:00 494次阅读