如何防止Class文件被反编译?

如何防止Class文件被反编译

--楼兰

带你聊最纯粹的Java

​ 各位伟大的Java程序员,现在有一条财富自由的路摆在你的面前,你有没有信心为此去挑战一下自己?

​ 这次我们来聊一个比较有意思的话题,如何防止Class文件被反编译。


Class反编译能财富自由吗?


​ 我们会编写各种Java代码,最终都是要以Jar包的形式放到JVM虚拟机中执行的。而Jar包当中包含的Class文件,虽然是个二进制文件,不能被人直接查看,但是,这些Class文件是可以被反编译的。在某些业务场景下,这就有可能是一个很大的安全隐患。

​ 例如,很多大型互联网产品,比如抖音、微信、淘宝、OpenAI等等,都会提供一个开放平台,对外暴露一些服务接口供第三方调用。在调用过程中,这些开放平台都会同时提供一个SDK工具包。通过这些SDK工具让第三方应用在调用服务时,能够更加简单。但是,这些SDK中需要很多非常重要的安全逻辑,包括数据加密、签名认证等。然而,如果这些SDK是用Java编写的,那么任何人都可以获取到这个SDK包,然后通过反编译的方式获取到数据加密的过程。

在这里插入图片描述

​ 此外,第三方应用向开放平台发送的数据,都是在互联网上传输的。这些互联网上的数据,也都可以通过一些抓包软件获取到。这就相当于加密的算法和加密后的结果都是所有人都可以获取的,那么,对于一些不怀好意的人来说,是不是就有可能通过逆运算获取到第三方应用提交的原始信息?这些原始信息里包含的很多秘密,也就自然而然的被别人偷过去了。

​ 当然,对于这些成熟的互联网开放平台来说,可以通过设计复杂的算法,提高反编译和逆运算的难度,并且,后台也会配合其他措施保证数据安全。但是,不得不说,这还是一个非常危险的事情。如果是一个你自己设计的开放平台,那么信息暴露的风险就非常大了。

​ 另外,Class文件反编译还有一个很大的市场就是Android。Android平台上有一个重要的开发语言Kotlin。而Kotlin本质上也是基于JVM执行的语言。也就是说,Kotlin编写的应用最终也会被编译成Class文件。也就是说,你手机上装的各种应用都正在被别有用心的人去反编译,并研究里面的漏洞。想想是不是就有点背后发凉?

​ 那么,各位程序员们,你们有没有想过,如果开发出一个Java安全工具,让Java编写的Class文件无法被反编译,这将是一个多么大的市场?一条通常财富自由的道路,就摆在我们面前。

​ 当然,这也并不是我在白日做梦。实际上,互联网上早就已经有了很多类似的产品存在了。比如这个allatori。

在这里插入图片描述

​ 那么接下来,咱们的主题就出来了。各位合伙人,我们能不能自己用Java开发一个对Java进行增强的工具,防止这些Class文件被反编译呢?接下来,楼兰就来带大家探探路,踩踩坑。


从一个OA系统计算工资的场景入手


​ 接下来,楼兰将通过一个具体的业务场景来详细讲解这件事情。用一个虚拟的OA系统来进行模拟。

在这里插入图片描述

​ 这里把计算工资的方法作为一个最为重要的核心逻辑进行设计。

偷偷给大家翻了一倍的工资,不要跟别人说哦。。。。

​ 现在计算工资的方法和整个OA系统是写在一起的,也就是说,别人只要拿到OA系统的Jar包,就能够通过反编译查看到SalaryCaler类。这样是非常不安全的。接下来,我们就需要实现一个工具,对SalaryCaler类进行保护,防止别人知道具体计算工资的方法。


第一步:将SalaryCaler抽取成扩展Jar包


​ OA系统太大了,无法加密,那就把SalaryCaler类从OA系统中删除掉。在另外一个新的SalaryCaler项目中实现。这样,就可以把新的SalaryCaler打成一个单独的Jar包,提供工资计算服务。

在这里插入图片描述

​ 这时,原来的OA系统,就需要引入这个新的Jar包才能够进行工资计算。

在这里插入图片描述

​ 这样就完成了OA系统与计算工资的SalaryCaler之间的解耦。计算工资的方法可以作为一个类似于开放平台的SDK开发包的方式使用。

​ 这时候,这个扩展Jar包的安全问题就开始暴露出来了。我们可以使用开源的JD-GUI工具对Jar包进行反编译,这样就能看到SalaryCaler类的计算工资逻辑了。

在这里插入图片描述

​ 接下来,我们就需要设计一个工具,对这个Jar包进行加密,防止别人进行反编译。


第二步:对Class文件进行加密


​ Jar包里包含的还是class文件,所以,这个工作还是要从class文件入手。

​ class文件是个二进制文件,他的内容到底张什么样子呢?我们可以使用Ultra Edit这样的工具直接打开SalaryCaler.class文件,查看他的二进制内容。

在这里插入图片描述

​ JVM对这些二进制内容定义了非常严格的规范。例如,class文件必须以十六进制的CAFEBABE开头,这就是规范的一部分。后面的四个字节 00 00 00 3D记录的是这个class文件是用哪个JDK版本编译出来的。3D转成十进制是61,这就是给JDK17分配的版本号。这就意味着这个class文件只能被JDK17以及以后的JDK执行。如果用JDK8就无法执行。其他的规范JDK官网有详细描述,这里就不一一解释了。如果大家感兴趣,我另行准备文档带大家解读解读。

​ 理解这个之后,就知道ClassLoader类加载器的作用。其实就是要读取这些二进制内容,然后交给JVM执行。

​ 接下来,如果我们可以将这个class文件的二进制内容稍微动动手脚,让他不满足JVM的规范,自然别人就无法反编译了。

​ 例如,用下面的应用程序,就可以将.class文件转换成一个不符合JVM规范的.myclass文件。

package com.roy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileTrans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roykingw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值