手记

关于java类加密的思路以及结果

        曾经做过一段时间的java类加密处理,我最终得到的结论是类无法安全加密,比较恶心到想破解的人的方法就是多加判定,然后混淆。这里把加密的思路记录下来,并记录破解的方法,希望后续有相同想法的人拿来借鉴。

场景

        很多时候有些处理我们不想让别人知道,所以采用混淆的方法,但是混淆也带来了一定的麻烦,那就是不能调试,遇到问题查找是个麻烦,于是想到通过加密类来解决这个问题。

基本想法

        由于处理的手段不想让别人知道,那么处理的类需要被加密,最简单就是需要加密的类单独成一个jar包,然后这个jar包自己来做一个加密。这样jar包的文件结构就被破坏了,无法正常被打开。

        众所周知,java类是被classloader加载的,正常的classloader是没有解密的功能的,所以我们需要一个自定义的classloader来做这个事情。同时解密的方法也暴露了出来。这就带来了一个很大的麻烦,解密方法暴露了那就一点意义没有了。

        为了让解密的方法隐藏起来,想到了用jni的方式来做解密的过程,然后用jni反调java中classloader的defineclass方法来做类的加载。并且返回一个加载后的对象。

        下面介绍一些jni的常用用法

        jni对字符串的处理 https://my.oschina.net/xpbob/blog/600133

        jni对一维数组的处理 https://my.oschina.net/xpbob/blog/600453

        jni对二维数组的处理 https://my.oschina.net/xpbob/blog/600788

        jni对对象的处理 https://my.oschina.net/xpbob/blog/601237

        jni对不同平台的处理和异常处理 https://my.oschina.net/xpbob/blog/601251

        当时在多个平台上测试,并且记录了对应平台的编译方法 https://my.oschina.net/xpbob/blog/610809

破解的方法

       因为一直是围绕着classloader来做的,所以实际走的还是java的方法,使用jni解密只是比java解密更难处理一点,但本质也是利用defineclass的方法来做的,所以本质的问题没有改变,那就是得通过Java的机制来加载字节码到内存。所以比较简单的一个破解方法就是ClassFileTransformer,实现这个接口的话就会有如下的一个方法    

public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException

        从这个方法中可以看到classloader,className,classfileBuffer(字节码的byte数组),这里可以获取到类名和类的内容,只要写出来,加密的部分就被还原了。使用的方法就是javaagent,有兴趣的可以查看一下。

结论

        依靠在classloader上做手脚是达不到保密的,破解方法就在上面可能比较暴力,但是是一个最简单的破解方法。想简单一些还是依靠混淆。

         

0人推荐
随时随地看视频
慕课网APP