尹艳阳,任洪敏
(上海海事大学信息工程学院,上海 201306)
Java软件保护机制的研究与实现
尹艳阳,任洪敏
(上海海事大学信息工程学院,上海 201306)
软件保护是一个困扰软件行业开发者的问题,特别是在当今互联网飞速发展且强调知识产权的时代,更应该引起业界的足够重视。Java语言以其“一次编译,到处运行”等众多优点占据着编程语言排行榜第一的位置。但是天生的特性使其非常容易通过各类反编译软件反编译得到源代码,致使Java软件安全面临着巨大危险。因而提出Java软件序列号方式实现授权,对序列号和Java类文件分别加密,在自定义加载类中解码编译,并用混淆器做代码混淆。结果表明Java软件无任何异常同时实现保护作用。
软件保护;类文件;自定义加载类;代码混淆
软件的开发需要大量的人力、智力和财力的投入,是由一个人或团队协作完成的高强度脑力劳动的结晶,是以知识、经验和智慧为基础具有创造性的产物。与有形财产一样,也应受到保护,以提高开发者积极性和创造力,促进软件行业发展。但它同一般物质性商品有明显的差别,软件产品的复制(批量生产)是极其简单的,其复制成本同其开发成本相比较,几乎可以忽略不计。
Java语言在知识产权保护方面有着天然的劣势,Java代码经过编译后产生字节码,但是字节码能够通过反编译从而获得到软件源代码的,从而来推导出软件产品所使用的思路、结构、算法、原理、运行方法、处理过程等具有知识产权的设计要素,这样就使Java软件的安全和知识产权受到严重威胁。
目前已经有多种技术方法来限制反编译或者提升反编译的难度。本地编译技术是把 Java程序编译成为能够在特定计算机上运行的应用程序。编译后产生的是本地可执行的二进制文件,使得用户无法通过反编译获得源代码,但此方法破坏了Java语言的可移植性。数字水印是在软件产品中嵌入的标识信号,数字不破坏软件的使用价值和使用体验。但是水印技术不是从本质上解决反编译问题,只是提供了有反编译行为时的证据。代码混淆(Obfuscated code)也称之为花指令,是保持软件程序功能等价的基础上对源代码做复杂的再组织和加工,令阅读和理解代码增加难度。
在Java软件保护方面,本文提出Java软件以序列号方式授权,用户必须拥有合法身份使用软件,对于非法用户有排斥和惩治措施。以及对Java class文件加密,动态解密。该方案的主要思想是:由程序获得运行计算机唯一标识MAC地址,对唯一标识做RSA公钥加密作为软件序列号。同时对选择的类文件加密,然后在类文件被加载调用时对其进行解密,在动态解密过程中随机对序列号进行检测,从而实现对 Java源代码的保护。然后对加载类和部分代码做混淆。
2.1 Java软件序列号授权设计
本文提出的Java软件保护机制的序列号方式授权的主要思路过程可以分为如下步骤:①将程序获得运行机的唯一标识MAC地址以及用户提交用户信息交由开发者;②开发者对计算机唯一标识和用户信息进行处理,做加密作为软件序列号,然后将软件的序列号发送给用户;③用户输入软件序列号并保存在软件配置文件中,由本地程序判断序列号的合法性,检查用户是否为合法身份。Java软件序列号授权过程整体流程如图1所示。
图1
2.2 class文件加密设计
(1)加密类文件
利用 Java Security包中加密扩展接口结合 RSA加密算法来对 Java应用程序里关键核心类文件和数据进行加密。加密后class文件不再是符合规则的字节码文件,而是变成反编译器无法打开的乱码文件,那么意味着反编译器为首的逆向工程工具无法从加密后的Java class文件中获得任何受保护的信息。整体思路如图2所示。
图2
(2)自定义加载器
类加载器 Classloader是Java运行环境的一部分,负责把Java类动态加载到Java虚拟机的内存里。每一个Java类必须由某个类加载器装入到内存中。Java虚拟机启动时,虚拟机内有三个默认的类加载器,形成类加载器层次:Bootstrap ClassLoader是用本地代码实现的,它负责加载Java核心库 (存储在 图3 在Java软件开始运行时,Java虚拟机将自定义的类加载器载入JVM内存中。在自定义ClassLoader中调用findClass方法实现父亲委托。所谓的父亲委托机制就是自定义加载器委托父加载器(Common)加载Class,Common委托System加载器,System委托BootStrap,如果BootStrap不能加载,则让Sys加载,逐级下发,如果直到自定义 ClassLoader还不能加载 Class这抛出ClassNotFindException。委托机制被提出的最初原因是为安全性考虑的,为了确保Object等重要类只可由JVM加载。要特别说明的是加载器之间的父子关系与类之间的继承关系不是同一概念,指的是加载器彼此的包装关系。在本方案中,自定义的类加载器通过读取配置文件中的参数,实现查找辨别完成解密处理后完成类文件的加载。请求加载过程如图 4所示。 2.3 混淆设计 Java Obfuscator的原理就是将字节码转换为一个逻辑上的对等物,这种转换后的版本极难拆散。即使有人试图去反编译,过程将极其艰难复杂,并很难绕过转换后模糊晦涩的编码。主要的过程如下: 用一个常规编译器(例如JDK)编译Java源代码运行混淆器,在受保护的环境下生成编译类文件。最后生成的会是一个不同的输出文档,也许扩展名也会不同。这个被重命名为.class file的文件在功能上与原字节码是对等的,由于虚拟机仍然可以对其进行解译,因此对功能不会产生影响。 图4 3.1 Java软件序列号的生成 将程序获得的计算机唯一标识,用户提交的用户信息,提交注册时间戳,随即字符串做为Java软件序列号生成的参数,通过处理得到序列号。如式(1)。 在检查序列号正确性时,对用户输入的序列号做MD5加密与用户名判断是否为特定值,同时与MAC、用户信息做对比,如果身份合法则调用装载器将软件加密部分做解密处理装入内存,初始化JVM虚拟机环境并运行Java软件,否则终止退出。如式(2): 3.2 自定义加载类的实现 使用自定义的类加载器 ClassLoader:在自定义ClassLoader中调用findClass()方法判断类是否己经是需要解密的类文件,如果是普通未被做加密处理的类文件,则交给父类Webapp加载类的findClass()方法负责加载;否则由自定义加载器调 findClassEncrypt()方法来载入className,这样被 className直接或间接引用的Java类都将由自定义加载类DeryptClassLoader载入。自定义加载类调入方法核心代码如下所示: 自定义加载类调入过程详细说明: (1)判断此Class有没有载入过(即在cache中是否有此Class),如果有到(8),如果没有到(2)。 (2)如果parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到(4);如果存在,到(3)。 (3)请求parent classloader载入,如果成功到(8),不成功到(5)。 (4)请求JVM从bootstrap classloader中载入,如果成功到(8)。 (5)查找Class文件(在和该classloader有关的类路径中查找)。找到了到(6),如果找不到则到(7)。 (6)从文件中载入Class,到(8)。 (7)抛出ClassNotFoundException。 (8)返回Class. 在 Java软件加载自定义加载类和对加密后的class文件进行解密的过程中,添加一个随机调用序列号判断方法,概率控制在10%,该方法用于进行检测用户身份合法性,对于非法用户有排斥和惩治措施。 3.3 代码混淆的实现 使用Zelix KlassMaster混淆器,它是一款用Java写的实用工具,能读取和修改Java类文件。该工具综合了控制流模糊处理和异常模糊处理技术,对Java字节码文件进行混淆处理。含有对字符串加密技术,加密后的字符串存储在常量池中。同时它提供了命名混淆功能,以降低项目包、类、字段、方法名称字节码大小。下图为例子HelloWorld混淆之后代码。 图5 运行class文件加密程序,选择要加密的class文件。运行效果图6: 图6 用加密过的class文件替换掉原未被加密的class文件 将自定义的加载器打成jar包放在lib文件夹中。并在context.xml里 用JD-GUI等反编译软件测试反编译加密后的class文件结果无法打开。 测试在class文件加密后,项目依然可以正常运行。加密后的字节码文件对比如图。 图7 图8 由于class文件的加密,在加载时有解密的过程,必然会消耗一些时间,降低一点运行效率。实验用了几组不同大小的class文件做测试性能分析,发现系统执行效率与加密的class文件大小存在线性关系。 任何的软件保护都并不是无法攻克的城池,但作为保护软件安全和知识产权的最后一道关卡,要尽可能地阻止和增加破解的代价。本文主要研究了一套Java软件的保护方案,实现了在不影响Java软件正常运行的情况下完成了对Java软件的保护。通过Java软件序列号方式实现授权。以两种加密方式对序列号和Java类文件分别加密,在自定义加载类中解码编译。用Java混淆器做代码混淆。详解了部署过程和方法,对测试结果做了判断分析,证明该方案起到了保护作用。 [1]Eckel B.Java编程思想[M].机械工业出版社,2007 [2]SHorstmann G,Cornell G.Java核心技术 卷II:高级特性[M].机械工业出版社,2008. [3]探矽工作室.深入嵌入式Java虚拟机[M].中国铁道出版社,2003. [4]梁栋.Java加密与解密的艺术[M].机械工业出版社,2010 [5]周志明.深入理解Java虚拟机:JVM高级特性与最佳实践[M].机械工业出版社,2011 [6]Herbert Schildt著.Java:The Complete Reference.张良华等译.电子工业出版社,2008 [7]Jason Brittain著.Tomcat权威指南.O’Reilly Taiwan译.中国电力出版社,2004 [8]Alex Kalinovsky.透视Java-反编译、修补和逆向工程技术[M].清华大学出版社,2005 [9]Joshua Bloch.《Effective Java中文版》第二版 [M].机械工业出版社,2009 Software Protection;Class Files;Custom ClassLoader;Code Obfuscation Research and Implement of Java Software Protection Mechanism YIN Yan-yang,Ren Hong-min Software protection is a troubled developer of software industry,particularly the rapid development of the Internet in today's era of intellectual property rights and stressed,should arouse enough attention to the industry.Java language with its"compile once,run anywhere" and many other advantages list of programming languages occupy the first position.However,the natural features make it very easy to decompile the source code through various decompile software,resulting Java software security is facing great danger.Therefore,proposes ways Java software serial number authorization for serial numbers and Java class files are encrypted,in a custom compiled loaded class decoding,and code obfuscation to do with confusion.The results show no protective effect of Java software while achieving the exception. 1007-1423(2016)19-0027-05 10.3969/j.issn.1007-1423.2016.19.008 尹艳阳(1990-),男,吉林梅河口人,硕士,研究方向为软件开发方法与软件管理 任洪敏 (1969-),男,上海人,博士,副教授,研究方向为软件体系结构、构件技术、软件复用、过程工程、软件项目管理 2016-05-04 2016-06-303 Java软件保护的实现
4 Java软件保护部署及测试
5 结语
(College of Information Engineering,Shanghai Maritime University,Shanghai 201306)