目前关于Java程序的加密方式不外乎JAVA模糊处理(Obfuscator)和运用ClassLoader方法进行加密处理这两种方式(其他的方式亦有,但大多是这两种的延伸和变异)。这两种方式不管给JAVA反编译器造成多少困难, 毕竟还是有迹可寻,有机可乘的。本文介绍的方法是对ClassLoader方式加密处理的一种改进,使之达到传统二进制程序代码安全。
第一章 流行的加密方式简介
关于JAVA程序的加密方式,一直以来都是以JAVA模糊处理(Obfuscator)为主。这方面的研究结果也颇多,既有模糊器(如现在大名鼎鼎的JODE),也有针对反编译器的"炸弹"(如针对反编译工具Mocha的 "炸弹" Crema和HoseMocha)。模糊器,从其字面上,我们就可以知道它是通过模糊处理JAVA代码,具体的说,就是更换变量名,函数名,甚至类名等方法使其反编译出来的代码变得不可理解。举个例子来说吧。
先将将下面源代码编译成class文件。
public class test
{
int sortway;
void sort(Vector a)
{
……
}
void setSortWay(int way)
{
……
}
void sort(Vector a, int way)
{
……
}
}
后通过JODE进行模糊处理后,反编译过来后, 可能变成下列代码。
public class OoOoooOo0Oo0O
{
int OoOo0oOo0Oo0O;
void OoO0ooOo0Oo0O (Vector OoOoo0Oo0OoOO)
{
……
}
void OoOo00oOoOo0O (int Oo0oooOo0Oo0O)
{
……
}
void OoO0ooOo0Oo0O (Vector OoOoo0Oo0OoOO, int Oo0oooOo0Oo0O)
{
OoOo00oOoOo0O (Oo0oooOo0Oo0O);
OoO0ooOo0Oo0O (OoOoo0Oo0OoOO);
}
}
其实这只是做到了视觉上的处理,其业务逻辑却依然不变,加以耐心,仍是可以攻破的,如果用在用户身份验证等目的上,完全可以找到身份验证算法而加以突破限制。
而所谓的"炸弹"是针对反编译工具本身的缺陷,这种方法对于特定的反编译工具是非常有效的,然而到目前为止,还没有一个全能型的,对每一种反编译工具皆有效,其局限性是明显的!
另一种方法是采用ClassLoader加密。JAVA虚拟机通过一个称为ClassLoader的对象装来载类文件的字节码,而ClassLoader是可以由JAVA程序自己来定制的。ClassLoader是如何装载类的呢?ClassLoader根据类名在jar包中找到该类的文件,读取文件,并把它转换成一个Class对象。该方法的原理就是,对需加密的类文件我们先行采用一定的方法(可以是PGP, RSA, MD5等方法)进行加密处理,我们可以在读取文件之后,进行解密后,再转换成一个Class对象。
关于ClassLoader工作方式的详细介绍就不在此一一述说了,前面已有文章专题讨论了。
有没有发现,该方法并未解决ClassLoader本身的安全性? 显然,只要反编译了该ClassLoader类,就可以顺藤摸瓜找到其它的类了。可见ClassLoader本身"明码"方式仍然造成一定的不安全性,然而,如果该方法解决了ClassLoader本身的安全性,其不失为一个比较好安全方案。