java诞生于1995年,是一门较年轻的语言。它以平台无关性,安全性,面向对象,分布式,键壮性等特点赢得了众多程序员的青睐。特别是它简洁的面向对象的语言风格,更让许多人对它爱不释手。但人们在使用java的过程中,会发现它有几个致命的弱点:运行速度慢,用户使用不便,源代码保护机制不够安全。特别是在保护源代码方面,java是基于解释一种叫java字节码的中间代码来运行其程序的,而且jvm比计算机的微处理器要简单的多,文档也很齐全,结果造成其目标程序很容易被反编译,而且所得代码和其原始代码十分相似,甚至可以一模一样,可读性相当好。这就给java的代码保护带来了不利。但要实现java程序的保护,也不是不可能的,经研究和总结,至少有三种实现方式:1.混淆器;2.网络加载重要类;3加密重要类。1 混淆器 目前,开发人员使用的比较多的保护代码的方法是用混淆器。混淆器是采用一些方法将类,变量,方法,包的名字改为无意义的字符串;使用非法的字符代替符号;贴加一些代码使反编译软件崩溃;贴加一些无关的指令或永远执行不到的指令等使反编译无法成功或所得的代码可读性很差。这样就实现了反反编译的目的。我们来做个演示。原始代码如下: import java.io.*; import java.security.*; public class sKey_kb{ public static void main(String args) throws Exception{ FileInputStream f=new FileInputStream("key1.dat"); ObjectInputStream b=new ObjectInputStream(f); Key k=(Key)b.readObject(); byte kb=k.getEncoded(); FileOutputStream f2=new FileOutputStream("keykb1.dat"); f2.write(kb); for(int i=0;i,这里就不祥述了)。加密完成后,就是通过解密来获取原始类的java字节码。可以通过一个DecryptStart程序运行经过加密的应用。 具体方法如下:public class DecryptStart extends ClassLoader { private SecretKey key; private Cipher cipher; public DecryptStart( SecretKey key ) throws GeneralSecurityException,IOException { this.key = key; String algorithm = "DES"; SecureRandom sr = new SecureRandom(); System.err.println( "[DecryptStart: creating cipher]" ); cipher = Cipher.getInstance( algorithm ); cipher.init( Cipher.DECRYPT_MODE, key, sr ); } // main过程:我们要在这里读入密匙,创建DecryptStart的 static public void main( String args ) throws Exception { String keyFilename = args[0]; String appName = args; String realArgs = new String[args.length-2]; System.arraycopy( args, 2, realArgs, 0, args.length-2 ); System.err.println( "[DecryptStart: reading key]" ); byte rawKey = Util.readFile( keyFilename ); DESKeySpec dks = new DESKeySpec( rawKey ); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance( "DES" ); SecretKey key = keyFactory.generateSecret( dks ); DecryptStart dr = new DecryptStart( key ); System.err.println( "[DecryptStart: loading "+appName+"]" ); Class clasz = dr.loadClass( appName ); String proto = new String; Class mainArgs = { (new String).getClass() }; Method main = clasz.getMethod( "main", mainArgs ); Object argsArray = { realArgs }; System.err.println( "[DecryptStart: running "+appName+".main()]" ); main.invoke( null, argsArray ); } 虽然应用本身经过了加密,但启动程序DecryptStart没有加密。攻击者可以反编译启动程序并修改它,把解密后的类文件保存到磁盘。降低这种风险的办法之一是对启动程序进行高质量的模糊处理。或者,启动程序也可以采用直接编译成