首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Linux频道
中国IT教育
Google
首页 资讯动态 认证考试 新手入门 核心技术 高级技术 J2EE J2ME Java&XML 开源技术 其他技术 RSS订阅 论坛 专题
您现在的位置: 中国IT实验室 >> Java >> 核心技术 >> 高级编程 >> 正文

JAVA语言安全行研究--Java的反编译

  其实,要实现这一点,并不难,只需要对一些重要的类实行加密就可以了。当然,在装载时,加密的类是需要解密才能被ClassLoader识别的。所以,我们必须自己创建ClassLoader类。在标准Java api中ClassLoader有几个重要的方法。创建定制ClassLoader时,我们只需覆盖其中的一个,即loadClass,添加获取原始类文件数据的代码。这个方法有两个参数:类的名字,以及一个表示JVM是否要求解析类名字的标记(即是否同时装入有依赖关系的类)。如果这个标记为true,我们只需在返回JVM之前调用resolveClass.

  原代码如下:

public Class loadClass( String name, boolean resolve )
  throws ClassNotFoundException {
  try {
  Class clasz = null;
  //步骤1:如果类已经在系统缓冲之中,我们就不需要再次装入它
  clasz = findLoadedClass( name );
  if (clasz != null)
  return clasz;
  byte classData[] = /* 通过某种方法获取字节码数据 */;
  if (classData != null) {
  clasz = defineClass( name, classData, 0, classData.length );
  }
  //步骤2:如果上面没有成功,
  if (clasz == null)
  clasz = findSystemClass( name );
  //步骤3:如有必要,则装入相关的类
  if (resolve && clasz != null)
  resolveClass( clasz );
  return clasz;
  } catch( IOException ie ) {
  throw new ClassNotFoundException( ie.toString() );
  } catch( GeneralSecurityException gse ) {
  throw new ClassNotFoundException( gse.toString() );
  } }

  代码中的大部分对所有ClassLoader对象来说都一样,但有一小部分是特有的。在处理过程中,ClassLoader对象要用到其他几个辅助方法:findLoadedClass:用来进行检查,以便确认被请求的类当前是否存在,loadClass方法应该首先调用它。defineClass:获得原始类文件字节码数据之后,调用defineClass把它转换成对象,任何loadClass实现都必须调用这个方法。findSystemClass:提供默认ClassLoader的支持。如果用来寻找类的定制方法不能找到指定的类,则可以调用该方法尝试默认的装入方式。resolveClass:当JVM想要装入的不仅包括指定的类,而且还包括该类引用的所有其他类时,它会把loadClass的resolve参数设置成true.这时,我们必须在返回刚刚装入的Class对象给调用者之前调用resolveClass.

  接下来就是加密解密部分。Java加密扩展即Java Cryptography Extension,简称JCE,是Sun的加密服务软件,包含了加密和密匙生成功能。我们可以用DES算法加密和解密字节码。用JCE加密和解密数据是要遵循一些基本步骤的(可以参考<>,这里就不祥述了)。

  加密完成后,就是通过解密来获取原始类的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[1];   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[1];   Class mainArgs[] = { (new String[1])。getClass() };   Method main = clasz.getMethod( "main", mainArgs );   ObJect argsArray[] = { realArgs };   System.err.println( "[DecryptStart: running "+appName+".main()]" );   main.invoke( null, argsArray );   }

  虽然应用本身经过了加密,但启动程序DecryptStart没有加密。攻击者可以反编译启动程序并修改它,把解密后的类文件保存到磁盘。降低这种风险的办法之一是对启动程序进行高质量的模糊处理。或者,启动程序也可以采用直接编译成机器语言的代码,使得启动程序具有传统执行文件格式的安全性。比如使用Java的Jini技术,来实现解密部分,就可以作到。当然,这是需要付出一定的代价的,就是丧失了Java的最大特点——平台无关性。不过,Jni技术可以用c语言在多种平台实现,我们可以在不同的平台编写不同的启动程序。

  4 综合实例:

  对于一些需要网络支持的软件来说,可以建立一个Web站点,在站点上存放该软件的关键类,并且建立用户管理机制,用户直接登陆网站进行确认,是许可用户,则发放解密key文件,让其下载关键类,在本地解密运行。这样作的优点是建立的Web站点可以有效的管理密钥以及用户资料。从而起到加强保护软件源代码的作用,并方便软件升级。用C/S结构是不错的选择。

上一页  [1] [2] 

【责编:John】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·关于Java框架技术专题
 ·XML全攻略技术专题
 ·JAVA开源技术介绍专题
 ·Java嵌入式开发之J2ME技术专题
 ·超前体验 Oracle 11g的5个新特性…
 ·揭密使用VB.NET的五个实用技巧
 ·Oracle和SQL Server常用函数对比专题…
 ·展现C#世界 C#程序设计专题…
 ·Java入门 Tomcat的配置技巧精华专题…
 ·Oracle RMAN物理备份技术详解…
 今日更新
 社区讨论
 博客论点
 频道精选
 Java 频道导航