您好,欢迎访问三七文档
陕西职业技术学院计算机科学系学生毕业论文11Java程序的保护摘要由于Java语言面向对象和编译成中间代码执行的特点,其在抗反编译和反盗版方面显得尤其脆弱。本文针对Java软件的特点,运用多种方法,综合设计出一个保护Java类文件的方法。Java是一种跨平台的、解释型语言。Java源代码编译中间“字节码”存储于class文件中。Class文件是一种字节码形式的中间代码,该字节码中包括了很多源代码的信息,例如变量名、方法名等。因此,Java中间代码的反编译就变得非常容易。目前市场上有许多免费的、商用的反编译软件,都能够生成高质量的反编译后的源代码。所以,对开发人员来说,如何保护Java程序就变成了一个非常重要的挑战。本文首先讨论了保护Java程序的基本方法,然后对代码混淆问题进行深入研究,最后结合一个实际的应用程序,分析如何在实践中保护Java程序。关键词:Class;加密;密钥;代码混淆目前,Java编程语言的应用在全世界范围正流行,它广泛的应用在Internet的数据库、多媒体、CGI及动态网页的制作方面。1999年在美国对Java程序员的需求量首次超过C++。经调查统计,Java语言应用在软件领域占领着举足轻重的地位,为人类科技文明进步奠定了重要基础。然而,Java语言却存在着巨大的安全隐患。Java是一种跨平台的、解释型语言。第一,Java源代码编译中间“字节码”存储于Class文件中。Class文件是一种字节码形式的中间代码,该字节码中包括了很多源代码的信息,例如变量名、方法名等;第二,由于跨平台的需求,Java的指令集比较简单通用,较容易得出程序的语义信息;第三,Java编译器将每一个类编译成一个单独的文件,这也简化了反编译的工作;第四,Java的Class文件中,仍然保留所有的方法和变量的名称,可以通过这些名称来访问变量和方法,这些符号往往带有许多语义信息。因此,Java程序的这些特点,很容易对不经过处理的Java程序进行反编译。目前,市场上有许多优秀的Java反编译工具,能够反编译出非常接近源代码的程序。所以,对开发人员来说,如何保护Java程序就变成一个非常重要的任务。陕西职业技术学院计算机科学系学生毕业论文22第一章JAVA类文件的安全威胁1.1JAVA的编译开发Java应用程序首先是使用编辑工具编写Java的源代码,然后使用编译器编译成虚拟机可执行的Class类文件。编译后生成的类文件是一种有格式的中间代码——字节码文件,不能在本地机器上独立运行,只能在Java虚拟机里解释执行。Java编译器不对变量和方法等符号的引用转换为数值引用,也不确定程序执行过程中的内存布局,而是将这些符号的引用信息保留在类文件中,由解释器在运行过程中创建内存布局,然后再通过查找表来确定一个变量或方法所在的地址[1]。从Java类文件的结构及其实际数据可知Java类文件保留了源代码文件的大部分信息,如所有的变量和方法等信息。正是由于这个特点,只要在各个平台上实现了各自的Java虚拟机,不用修改Java应用程序的源代码就可以在各个平台上运行,真正做到跨平台的特性,这也是Java能够迅速流行起来的重要原因。1.2JAVA的反编译反编译是一个将目标代码转换成源代码的过程[2]。而目标代码是一种用语言表示的代码,这种语言能通过实机或虚拟机直接执行。从本质上说,他需要根据小规模、低层次的行为来推断大规模、高层次的行为。因此,反编译目标代码并不容易。在JDK中,有一个反编译器javap[3],利用该工具可以对Java类文件进行反编译。经过该工具反汇编后得到的结果并不是源代码,但是使用javap进行反编译的Java类文件可以得到成员变量、方法、行号以及局部变量名等信息[4]。在javap工具的基础上,一些反编译工具如Mocha,WinDis,DjDecompiler等工具可反编译出和源代码几乎一摸一样的代码。第二章JAVA语言Java语言的优点主要表现在:简单、面向对象、多线程、分布性、体系结构中立、安全性等方面2.1简单性Java与C++语言非常相近,但Java比C++简单,它抛弃了C++中的一些不是绝对必陕西职业技术学院计算机科学系学生毕业论文33要的功能,如头文件、预处理文件、指针、结构、运算符重载、多重继承以及自动强迫同型。Java实现了自动的垃圾收集,简化了内存管理的工作。这使程序设计更加简便,同时减少了出错的可能。2.2面向对象Java提供了简单的类机制和动态的构架模型。对象中封装了它的状态变量和方法,很好地实现了模块化和信息隐藏;而类则提供了一类对象的原型,通过继承和重载机制,子类可以使用或重新定义父类或超类所提供的方法,从而既实现了代码的复用,又提供了一种动态的解决方案。Java是一种完全面向对象的程序设计语言,它除了数组、布尔和字符三个基本数据类型外的其它类都是对象,它不再支持全局变量。在Java中,如果不创建新类就无法创建程序,Java程序在运行时必须先创建一个类的实例,然后才能提交运行。Java同样支持继承特性,Java的类可以从其它类中继承行为,但Java只支持类的单重继承,即每个类只能从一个类中继承。Java支持界面,界面允许程序员定义方法但又不立即实现,一个类可以实现多个界面,利用界面可以得到多重继承的许多优点而又没有多重继承的。2.3多线程多线程使应用程序可以同时进行不同的操作,处理不同的事件。在多线程机制中,不同的线程处理不同的任务,他们之间互不干涉,不会由于一处等待其他部分,这样容易实现网络上的实时交互操作。Java程序可以有多个执行线程,如可以让一个线程进行复杂的,而让另一个线程与用户进行交互,这样用户可以在不中断计算线程的前提下与系统进行交互。多线程保证了较高的执行效率。2.4分布性Java是面向网络的语言。通过它提供的类库可以处理TCP/IP协议,用户可以通过URL地址在网络上很方便的访问其他对象。2.5体系结构中立Java是一种网络语言,为使Java程序能在网络的任何地方运行,Java解释器生成与体系结构无关的字节码结构的文件格式。Java为了做到结构中立,除生成机器无关的字节码外,还制定了完全统一的语言文本,如Java的基本数据类型不会随目标机的变化而变化,一个整型总是32位,一个长整型总是64位。陕西职业技术学院计算机科学系学生毕业论文44为了使Java的应用程序能不依赖于具体的系统,Java语言环境还提供了用于访问底层操作系统功能的类组成的包,当程序使用这些包时,可以确保它能运行在各种支持Java的平台上。java.lang:一般的语言包。其中包括用于字符串处理、多线程、异常处理和数字函数等的类,该包是实现Java程序运行平台的基本包java.util:实用工具包。其中包括哈希表、堆栈、时间和日期等java.io:基于流模型的输入/输出包。该包用统一的流模型实现了各种格式的输入/输出,包括文件系统、网络和设备的输入/输出等java.net:网络包。该包支持TCP/IP协议,其中提供了socket、URL和抽象窗口工具集。其中实现了可以跨平台的图形用户界面组件,包括窗口、菜单、滚动条和对话框等java.applet:支持applet程序设计的基本包2.6安全性用于网络、分布环境下的Java必须要防止病毒的入侵,Java不支持指针,一切对内存的访问都必须通过对象的实例变量来实现,这样就防止了程序员使用欺骗手段访问对象的私有成员,同时也避免了指针操作中容易产生的错误。第三章常用JAVA类文件的保护方法3.1JAVA类文件的保护方法由于Java字节码的抽象级别较高,容易被反编译,所以就有了多种防止Java字节码被反编译的方法。隔离Java程序:最简单的方法就是让用户不能够访问到JavaClass程序,这种方法是最根本的方法,具体实现有多种方式。代码混淆:这种方法对Class文件进行重新组织和处理,使得处理前后的代码具有相同的语义,被混淆后的代码很难被反编译。转换成本地代码:本地代码难以被反编译,开发人员可以选择将整个应用程序或关键模块转换成本地代码。如果仅仅转换关键模块,在使用这些模块时,需调用JNI技术,这将牺牲Java的跨平台特性陕西职业技术学院计算机科学系学生毕业论文55加密Class文件:为了防止Class文件被直接反编译,可以将一些关键的Class文件加密例如对密钥、加密算法、注册码、序列号管理相关的类等。在使用这些被加密的类之前先解密,然后再将其装载到JVM中。对比上述几种方法,都存在其自身的优缺点。隔离Java程序只能适合网络环境的客户机/服务器结构或者分布式的环境,对单机运行的程序就无法隔离,而且Java程序需要使用安全机制保护服务器开放接口的使用,服务器的安全成了整个系统安全的焦点。代码本地化,对于不同的平台,需要维护不同版本的本地代码,这将加重软件支持和维护的工作。对Class文件进行加密,在使用时再进行解密,同时将关键加密代码部分进行代码混淆,这样经过双重处理后,代码的安全性[6]提高了很多,该方法也是本文研究的重点。第四章class文件加密技术Java生成的Class文件大量暴露在客户端,利用现在的反编译工具可轻易的获取源代码,下面将讲叙如何有效的保护Class文件。4.1读取本工程的所有待加密Class文件,并保存到byte型数组中;publicstaticbyte[]symmetricEncrypt(byte[]key,byte[]classData){…};方法对读取到的所有Class文件进行加密,key为用来加密的密钥,classData为所读到的待加密Class文件,返回结果为加密后的Class文件,然后将其写回原来的Class中,保证结构的完整性。4.2加密过的Cl行解密,最后将解密后的类装载到JVM这里我的虚拟机有默认的类加载器,但是若要它根据用户提供的密码解密代码就难以做到,此时需要通过自定义ClassLoader类来完成加密类的装载。自定义的ClassLoader首先找到被加密过的类,然后进行解密,最后将解密后的类装载到JVM中。这里我的自定义ClassLoader如下:ClassLoaderappLoader=newEncryptedClassLoader(EncryptedClassLoader.class.getClassLoader(),newFile(args[1]));Thread.currentThread().setContextClassLoader(appLoader);陕西职业技术学院计算机科学系学生毕业论文66finalClassapp=appLoader.loadClass(args[2]);其中参数args[1]传入的是方法所在的工程名,args[2]为主函数所在的类名。在加载类后,系统的默认findClass()并未对加载的类作任何处理,由于Class文件已被加密过,此时若运用系统方法findClass()则会抛出ClassNotFoundException()的异常,所以这里需要重构我自己的findClass()方法:protectedClassfindClass(finalStringname)throwsClassNotFoundException{finalStringclassResource=name.replace('.','/')+.class;finalURLclassURL=getResource(classResource);InputStreamin=null;Filefile=newFile(classURL.getPath());byte[]classBytes=newbyte[(int)file.length()];FileInputStreamfin=newFileInputStream(file);fin.read(classBytes);……classBytes=decrypt(classBytes);//解密……returndefineClass(
本文标题:Java程序的保护
链接地址:https://www.777doc.com/doc-2878839 .html