Java类文件保护的研究及其实现 - 图文

更新时间:2024-05-15 01:42:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

浙江大学硕士学位论文

Java类文件保护的研究及其实现

姓名:鲍福良申请学位级别:硕士专业:软件工程指导教师:朱晓芸

20050301

Java类文件保护的研究及其实现摘要Java类文件保护的研究及其实现摘要编译后的Java类文件不是真正的二进制文件,丽是一种有格式的中间代码,这就给黑客反编译Java类文件提供了可能,反编译后的代码和源代码几乎没有差别。这样,一些作者含辛茹苦编写的源代码就会轻丽易举地被黑客窃取,一些重要的算法也会泄漏出去。因此Java应用程序也就毫无秘密可言,这样在源代码上就会产生很大的安全问题。近年来,已经有许多公司和Java开发人员对Java类文件和虚拟机进行了深入的分析,并在此基础上采取了各种方法来保护Java类文件,在一定程度上起到了保护Java类文件的作用。如本地编译技术、代码隔离技术、代码混淆技术以及数字水印技术等传统保护方法,但是都有各自的局限性。本文针对这种情况,在传统保护方法的基础上,结合JNI技术,为客户端应用程序实现了一个简单而又实用的Java类文件保护方法,主要的技术点有以下几个方面:(1)用c++实现的加密和解密算法来加密和解密Java类文件,并在定制的ClassLoader中采用JNI技术来调用本地解密库:(2)使用定制的ClassLoader替换Java虚拟机默认的ClassLoader来载入加密后的类文件。目前Java在Web应用程序的开发中广泛使用,而针对Web应用程序的Java类文件保护方法还是空白,本文结合上述客户端应用程序Java类文件的保护技术,创新的提出了使用Servlet接口和实现分离的机制:Servlet接口不变,实现部分转移到另外一个类并加密。加密后的Web应用程序和客户端应用程序一样,其安全强度可以达到本地应用程序的安全强度。关键词:Java,安全,类文件,字节码,本地接口,类加载器Java类文件保护的研究及其实现摘要ResearchandImplementationonProtectingJavaClassFilesAbstractThecompiledjavaclassfileisnotreallybinary;instead,it’Sjustakindofin-betweencode.Thismakesitpossibleforthehackerstodecompilethejavaclassfile,andinfactthedecompiledfileisalmosttheoriginal.Thus,thehackerscaneasilystealthesourcecodeandsomeimportantalgorithms.Soit’Shardtoprotectthejavaapplicationprogram,andthere’Sabigissueaboutthesecurityofjavaclassfile,Recently,manyresearcheshavebeendoneinthejavaclassfileandvirtualmachine,andalsomanymechanismshavebeenproposedtoprotectthejavaclassfile,theydoworkinsomedegree,suchasJIT,codeisolation,codeobfuscationandcodewatermaking.HoweveLAllthesemechanismshavetheirlimitationsrespectively.Thisthesisproposedasimpleandefficientmechanismtoprotectthejavaclassfileonthecustomerend,basedonthetraditionalways.Thenewmechanismhassomemainfeaturesasbelow:(1)EmploytheC++programtoencryptanddecryptthejavaclassfileintheClassLoader,usingthelocaldecryptionlibrarycalledbyJNI;f2)UsethecustomizedClassLoadertoloadthedecryptedclassfileinsteadofthejavavirtualmachine.Presently,javahasbeenwidelyusedintheWebapplicationprogramming,butisdonetoprotectthejavaclassfile.ThisthesisdescribedanovelmethodtothejavaclassfilesinthecustomersideWebapplicationprograms.ThenewemploysabrandnewmechanismtoseparatetheServlet’Sinterfaceandinterfaceremainsnotencrypted,andpartoftheimplementcodeswilltransferredtOanotherencryptionlibraryandencrypted;thismakestheWebprogramhasthesamesecuritylevelasthelocalprogram.File,ByteCode,JNI,ClassLoadercustomizeddefaultlittleprotectmethodimplement:thebeapplication关键词:Java,Security,ClassJava类文件保护的研究及其实现浙江大学硕上学位t&1.前言1.1.Java概述Java是由Sun公司开发而成的新一代编程语言。Java语言一推出就以其简单性、跨平台性等各种优秀特性赢得了许多著名公司的青睐。开发人员使用Java语言可以在各种机器、各种操作平台中开发应用程序。大量的开发人员、成熟的开发模式以及丰富的开发资源已经Java使成为企业级应用程序的主流开发工具。它彻底改变了应用软件的开发模式,带来了自PC机以来又一次技术革命,为迅速发展的信息世界增添了新的活力【22】。1.1.1.Java的特性Java作为一种程序设计语言,具有许多优秀的特性,如简单、面向对象、分布式、解释执行、鲁棒、安全、体系结构中立、跨平台、高性能、多线程以及动态性等[28]。(1)简单性Java语言是一种面向对象的语言,它通过提供最基本的方法来完成指定的任务,只需理解一些基本的概念就可以用它编写出适合的应用程序。Java略去了运算符重载、多重继承等模糊的概念,并且通过实现垃圾自动回收机制大大简化了开发人员的内存管理工作。另外,Java也适合于在移动设备上运行,它的基本解释器及类的支持只有40KB左右,加上标准类库和线程的支持也只有215KB左右。(2)面向对象Java语言的设计集中于对象及其接口,它提供了简单的类机制以及动态的接口模型。对象中封装了它的状态变量以及相应的方法,实现了模块化和信息隐藏:而类则提供了一类对象的原型,并且通过继承机制,子类可以使用父类所提供的方法,实现了代码的复用。(3)分布性Java是面向网络的语言。通过它提供的类库可以处理TCP/IP协议,用户可以通过URL地址在网络上很方便地访问其它对象。Java类文件保护的研究及其实现浙江大学硕士学位论文(4)鲁棒性Java在编译和运行程序时都要对可能出现的问题进行检查,以消除错误的产生。它提供垃圾自动回收机制来管理内存,防止开发人员在管理内存时容易产生的错误。通过集成的面向对象的异常处理机制,在编译时,编译器提示可能出现但未被处理的异常,帮助开发人员正确地进行选择以防止系统的崩溃。另外,Java在编译时还可捕获类型声明中的许多常见错误,防止动态运行时不匹配问题的出现。(5)安全性用于网络、分布环境下的Java必须要防止病毒的入侵。Java不支持指针,一切对内存的访问都必须通过对象的实例变量来实现,这样就防止程序员使用各种欺骗手段访问对象的私有成员,同时也避免了指针操作中容易产生的错误。(6)体系结构中立Java编译器生成与体系结构独立的字节码指令,只要安装了Java虚拟机,Java程序就可在任意的处理器上运行。(7)跨平台性与平台无关的特性使Java程序可以方便地被移植到网络上的不同机器。同时,Java的类库中也实现了与不同平台的接口,使这些类库也具有跨平台性。跨平台性使开发人员摆脱了机器的束缚,真正做到了~次编写,到处运行”。(8)解释执行Java解释器直接对Java字节码进行解释执行。字节码本身携带了许多编译时信息,使得连接过程更加简单。(9)高性能和其它解释执行的语言如Basic、Tel不同,Java字节码的设计使之能很容易地直接转换成对应于特定CPU的机器码,从而得到较高的性能。(10)多线程多线程机制使应用程序能够并行执行,而且同步机制保证了对共享数据的正确操作。通过使用多线程,开发人员可以分别用不同的线程完成特定的行为,而不需要采用全局的事件循环机制,这样就很容易地实现网络上的实时交互行为。(11)动态性Java的设计使它适合于一个不断发展的环境。在类库中可以自由地加入新的方法和实例变量而不会影响用户程序的执行。并且Java通过接口来支持多重继

Java类文件保护的研究及其实现浙江大学硕士学位论文承,使之比严格的类继承具有更灵活的方式和扩展性。1.1.2.Java的影响Java从】995年推出以来,不到10年时间就变成最流行的软件开发平台。虽然推出的时间不长,但已普遍被业界所接受。IBM、Apple、DEC、Adobe、SiliconGraphics、HP、0racle、Toshiba、Netscape和Microsoft等大公司已经购买了Java的许可证。另外,众多的软件开发商也开发了许多支持Java的软件产品。如Borland公司的基于Java的快速应用程序开发环境JBuilder:Bea公司开发的基于Java的应用服务器Weblogic:数据库厂商如Illustra,Sybase,Versant,Oracle也都在推出了支持Java的产品。随着Java在企业应用的日臻完善,诞生了一批如ebay.com这样重量级的应用方案,为此也打消了许多人对Java无法应用于大型企业级应用的顾虑。现在美国30%的大型企业都用Java开发关键性的应用,在中国也不例外。Java技术不光是大型企业、应用商的开发工具,同时也可以在手机、PDA上使用。在世界上目前大的手机』一商都已经使用Java开发了第三代电话[321。在将来,Java一定会成为我们生活中不可缺少的技术。1.2.Java类文件的安全1.2.1.Java的编译开发Java应用程序的过程是:首先使用编辑工具编写Java的源代码(扩展名为.java的文件),然后使用编译器(如idk自带的javac编译器)编译成虚拟机可执行的类文件(扩展名为.class的文件)。编译后生成的类文件是一种有格式的中间代码——字节码文件,不能在本地机器上独立运行,只能在Java虚拟机里解释执行。Java的这一编译过程和C/C++的编译过程有些不同。C/C++编译器编译生成的一个对象代码是为在某一特定平台运行的代码,编译器通过查找表将所有变量和方法等符号的引用转换为特定的内存偏移量[1]。而Java编译器却不对变量和方法等符号的引用转换为数值引用,也不确定程序执行过程中的内存布局,而是将这些符号的引用信息保留在类文件中,由解释器在运行过程中创建内存布局,然后再通过查找表来确定一个变量或方法所在的地址[3]。Java类文什保护的研究及其实玑浙江大学硕士学似论义1.2.2.Java类文件的格式Java类文件是对一个Java类或者是Java接口作出的全面描述。‘个Java类文件只能包含一个类或者接口。无论Java类文件在何种系统上产生,无论虚拟机在何种系统上运行,对Java类文件的精确定义使得所有Java虚拟机都能够正确的读取和解释所有的Java类文件。Java类文件是8位字节的二进制流。数据项按顺序存储在类文件中,相邻的项之间没有任何问隔,这样可以使类文件更加紧凑。占据多个字节空间的项按照高位在前的顺序分为几个连续的字节存放。和Java类可以包含多个不同的字段、方法、方法参数、局部变量等一样,Java类文件也能够包含许多不同大小的项。在类文件中,可变长度项的大小和长度位于其实际数据之前。这个特性使得类文件可以被从头到尾按顺序解析,首先读出项的大小,然后读出项的数据。一个Java类文件具有如F的结构[21]:Java类文件保护的研究及苴实虮浙扛大学硕士学位论义ClassFile结构巾的各个项的描述如下:(1)magic:Java类文件的魔数:0xCAFEBABE。魔数的作用在于可以轻松的分辨出Java类文件和非Java类文件。(2)minorversion和majorversion:Java类文件的主、次不版本号。(3)constant』ool和constantlpool—count:常量池和常量池的数量,常量池包含了与文件中类和接口相关的常量,如文字字符串、final变量值,类名和方法名等。(4)accessflags:表明了类或者接口的相关信息,如是类还是接口、修饰符、是否final等。(5)thisclass:常量池中表示当前类的数据项的索引,该数据项为必须CONSTANT_Class类型。(6)superclass:常量池中表示当前类的父类的数据项的索引,该数据项必须为CONSTANTClass类型.(7)interfaces:由interfacescollrtt个长度为u2的常量池数据项索引组成,所有相关的数据项必须为CONSTANT_Class类型,每一项均代表一个当前类或接口的直接父接口。(8)fields:成员变量集合,由fields_count个field_into类型的数据项组成。(9)methods:成员函数集合,由methods—count个methodinfo类型数据项组成。(10)attributes:由atributescount个attributeinfo类型的数据项组成。那么这个Java类文件的格式实际看上去是什么样呢?下面提供了一个(非常)简短的类的源代码,还附带了由编译器输出的类文件的部分十六进制显示:Java类文件保护的研究及其实现浙江大学硕士学位论义0000O0h10hCA口0FE1cBA09BEoo04096Doo000065616Eoo1D20736E690i2E0700ooD02izB1E0A6753Dio^oo0直00090qoolB1B074C000OD01F00231208:澈壕.….+...…...….......…D且;006A000020h00003002q61D10q0l76000000657400ZZ0172030000j.......}..”.撑..j{...rde3sage...L10h0口076106736774006l2F3E0F0l5q000040hD00050h000060h0000702F3C6FSq6C69646169286E29673B;ava/lan目,scrlnq;56口1;...<inlc>...CJV.7S610062560{436561686q7265626200qCD06169iZ626C0i6EqC6C6C0065乓E6F63h6C6C6565O000O0O80h90ha0h726969736101656F1601006C:berTable…Local0q;VarlableTable…6D:..Code...LineNum7q6C0C耳Cq86967656E21r5'6F286972;this...LHelloVorD003B7656610l6101002FO哼6D6C046l616i6ESB{C:Id;...Ilialn...C[L6E4CD000口db0h6鱼613B6153017.t74007z7772136967二1ava,lang/string0000c0h000Od0h0O00e0h0000fOh000100h002976006C616E0072670B672F737S577353SB6E65696且;;)V…arg,…【LJ3B;吖a/lang/scrlng;73:...hv...3hovl塘s32F67736C01610口0267006568’7010i0A6C002168726F63724D4600650C6qS36CDD0C6F6F0l00656C65;a口e…SourceFile6i;...珏elloⅡorld.1a01’6DF0C726rq8006CS76F6哩2E6C000D6C0A076A6Fq8000110h6l6F6C00OC乓80B186S01000120h576C0^000CD000口皿0130h6F726C6420:va.…....HelIo65;耵orld‘....….He2S:1lol40rld…....%图1类文件的二进制格式因此,从Java类文件的结构及其实际数据可以知道Java类文件中的信息是非常丰富的,其中保留了源代码文件中的大多数信息,如所有的变量和方法等信息。正是由于这个特点,只要在各个平台上实现了各自的Java虚拟机,不用修改Java应用程序就可以在各个平台上运行,真正做到了跨平台的特性,这也是Java能够迅速流行起来的重要原因。1.2.3.,Iava的反编译反编译是一个将目标代码转换成源代码的过程【2]。而目标代码是一种用语言表示的代码,这种语占能通过实机或虚拟机直接执行。反编译听上去比较简单,但他实际上不是很容易做到的。从本质上说,他需要根据小规模、低层次的行为来推断大规模、高层次的行为。为了对此有个直观的理鳃,我们把一个计算机程序看作是一个复杂的公司组织结构,高层管理人员向他们的下属下达类似“最大程度地提高技术生产能力”的命令,下属们再把这些命令转变成更具体的行动,例如安装新的XML数据库。你可能会问底层雇员他们在做些什么,得到回答“我在安装新的XML数据库”。从这句话中,你很难推断出其最终目的是最大程度地提高技术生产能力。因为,许多最终目标都有可能,例如分离供应链或累积消费者的数据。当然,如果你多问几个问题,并让公司中不同级别的雇员回答。那么,当把所有的答案汇总后,有可能会猜到企业更大的目标是最大程度地提高技术生产能力。因此,反编译目标代码并不容易,特别是对C/C++编译生成的二进制目标代码。在JDK中,有一个反汇编器javap[9],利用该工具可以对Java类文件进行反汇Java类文件保护的研究及其实现浙江大学硕士学位论文编,把上节的HelloWorld.class文件反汇编后得到的结果如下图2javap的输出结果请注意,经过反汇编后得到的结果并不是源代码。他的第一部分列出了方法的局部变量,第二部分是汇编代码。这里简要列出了可以通过使用javap进行反汇编的Java类文件所包含的信息【33]:(1)成员变量;(2)经过反汇编后的方法;(3)行号;(4)局部变量名。对Java类文件的内部情况有所了解后,黑客如果要进一步获得源代码的逻辑就会使用反编译器,反编译器使用起来比较简单,你给他Java类文件,他返还一个源代码文件。现在一些比较新的反编译器不但功能强大而且还有精致的图形界面。提到Java反编译器就不得不提到Mocha,作为第一个Java反编译器,Mocha一发布就引起了不少的震动[34]。作者HanpetervanVliet一发布这个软件就受到了儿个公司的诉讼威胁,它随后又发布了一个和Mocha相对立的Java混淆器Crema,它能够对Mocha的反编译进行干扰[341。一些反编译工具如Mocha,WinDis,DjDecompiler等能够反编译出和源代码

Java娄文件保护的研究及其实现浙江人学硕上学位论文儿乎一模。样的代码。下而是使用DjDecompiler反编译出以上类文件的结果。1.2.4.Java类文件的安全由于Java类文件不是真正的二进制文件,而是一种有格式的中间代码,这就给反编译Java类文件提供了可能。一一些反编译器具如Mocha,WinDis,DjDecompiler等能够反编译出和源代码几乎一模一样的代码。由于反编译后的代码和源代码几乎没有差别。这样,一些作者含辛茹苦编写的源代码就会轻而易举地被黑客窃取,一些重要的算法也会泄漏出去。因此Java应用程序也就毫无秘密可言,这样在源代码上就会产生很大的安全问题。产生上面这种现象的根本原因还是和Java语言的本身特性有关:●为了适应跨越多种平台的需要,Java虚拟机的指令集比本地的汇编指令集要简单得多,并且为各个半台所通用。这就使得反编译的复杂性降低了许多。●Java编泽器将每个类编译成一个单独的类文件,这也简化了反编译的1:作。Java类文竹中,仍然保留所有的方法和变量的名称,并JfLl!i过这些名称来访问变茸和方法,这些符号往往带有许多语义信息。●正足由于Java语言本身的简单和跨平台的特性决定了它能够很容易被反编译,所以Java类文件的保护就显得更加迫切。Java类文件保护的研究发其实现浙江大学硕士学位论文1.3.本文的工作近年来,已经有许多公司和Java开发人员对Java类文件和虚拟机进行了深入的分析,并在此基础上采取了各种方法来保护Java类文件,在一定程度上起到了保护Java类文件的作用。本文在传统保护方法的基础上,结合JNI技术,为客户端应用程序实现了一个简单而又实用的Java类文件保护方法,主要的技术点有以下几个方面:(1)用c++实现的加密和解密算法来加密和解密Java类文件,并在定制的ClassLoader中采用JNI技术来调用本地解密库;(2)使用定制的ClassLoader替换Java虚拟机默认的ClassLoader来载入加密后的类文件。目前Java已经在Web应用程序的开发中广泛使用,而针对该类应用程序的Java类文件保护方法还是空白,本文创新的提出了使用Servlet接口和实现分离的技术,并结合上述为保护客户端应用程序的相关技术来保护Web应用程序。Java类文件保护的研究及其实现浙江火学硕上学位论文2.客户机应用程序的传统保护方法Java开发的客户机应用程序是也俗称单机应用程序,其特征就是需要用iavac命令启动一个含有main0函数的应用程序。客户机应用程序的典型例子就是传统的GUI图形界面应用程序。目前所有的Java类文件的保护方法都是基于客户机应用程序的研究,本章讲详细分析这些传统的Java类文件保护方法。传统的Java类文件保护方法主要有以下几种方式:本地编译技术、代码隔离技术、代码混淆技术以及数字水印技术。下面将对这几种方法分别进行介绍。2.1.本地编译技术Java本地编译是指将Java应用程序编译成本地应用程序[421,如Windows操作系统上扩展名为exe的应用程序。其步骤如下:首先编写Java源代码,然后通过Java编译器将Java源代码编译成Java类文件,最后将Java类文件编译成真正的本机应用程序。这种解决方案将以牺牲跨平台性为代价,生成的本地应用程序是二进制格式的可执行文件,与在虚拟机中执行的Java应用程序相比,可以产生更快的执行速度和更小的内存占用,而且其安全性能也等价于本地可执行应用程序的安全强度,这些对于当今许多应用程序都很关键[101。目前市面上有很多的本地编译工具,如GCJ,{ove和ExcelsiorJET等,但是在使用了这些工具后,发现了以下几个问题:(1)失去了跨平台性;因为生成的本地应用程序是二进制格式的可执行文件,所以只能在某‘一种平台上运行,失去了跨平台的特性。因此,它是以牺牲Java语言最优秀的特性为代价。(2)不支持B/S结构的Java应用程序:本地编译后生成的应用程序是一个可执行程序,所以适用于普通的客户机应用程序。而目前流行的B/S结构的应用程序运行在Java应用服务器上,因此本地编译明显不支持这种类型的应用程序。(3)类支持/编译器成熟度:很多编译器仍然相对不太成熟,并且可能无法支持应用程序所需的所有Java类。例如,虽然GCJ支持大部分上至1.1版本规范的Java语言构造,但是,它不支持通常与JVM一起提供的所有Java类库。Java类文件保护的研究及其实现浙江大学硕士学位论义最重要的是,它几乎不支持AWT,这使GCJ无法适用于GUl应用程序。不同的编译器支持不同级别的类库;ExcelsiorJET声称是完全支持AwT和Swing的编译器。(4)支持/复杂程度:因为这个领域相对较新,所以诊断工具可能在基础上有点薄弱。因此要诊断本机编译产生的Java应用程序中发生的问题可能更困难(尤其当Java类文件版本中没有发生该错误时)。因此,本地编译技术能保护客户机应用程序中比较简单的应用程序,对于复杂的应用程序还支持得不够,对于B/S结构的应用程序还不支持『111。尽管本机编译技术已经有一段时间了,但是它还比较稚嫩,并且缺少明确的结果,但它却是Java语言中一个激动人心的新领域。事实已经证明,对于某些应用程序和环境,它是正确的解决方案[121。2.2.代码隔离技术代码隔离技术就是让用户访问不到类文件,如将类文件放在远程的服务器端,客户端通过访问服务器的相关接口来获得服务。这种方法使得黑客无法获得类文件,从而无法进行发编译。而且这种服务接口可以提高系统的可移植性和互操作性,大大降低软件的开发成本。现在通过接口提供服务的标准和协议也越来越多,如HTTP,RPC,WebService等。把类文件放在远程的服务端,这种模式就是现在流行的Java服务器应用程序,也称为Web应用程序。应用程序模式的发展不但是为了适应各种计算的需要,从另外~个方面看也起到了保护客户机应用程序的Java类文件的作用。有关Web应用程序的Java类文件的保护方法,在接下来的几个章节会有详细的叙述。代码隔离的方法能很好的起到保护Java类文件的作用。但是这种方式也有它的局限性和不安全性。首先这种方式只能适合网络环境的客户/服务器结构或者分布式的环境,对客户机运行的应用程序就显得无能为力了。其次,为了保障服务断的安全,需要使用安全机制保护服务器开放的接口的使用,服务器的安全成了整个系统安全的焦点。一旦服务器被攻破,Java类文件就很容易被窃取之后,接下来的反编译工作是非常容易,因此后果不堪设想。2.3.代码混淆技术代码混淆技术是目前比较成熟和流行的Java类文件保护方法[4]。它的原理Java娄文件保护的研究及其实现浙江火学硕上学位论文就是把类文什重新进行组织,使别人无法轻易的读懂反编译出来的代码,但是处理以后的类文件功能和处理以前的类文件功能在逻辑上是等同的,即运行后能够得到一样的输出结果。自从第一款Java的反编译器出现以后,代码的混淆技术和理论也得到了很大的发展。现在有多款比较流行的混淆器产品,比如JODE,jmangle,Jsrink等『151,Sun公司自己也有一款混淆器产品JADE,这款软件的评估版可以从Sun的网站免费获得。下面是一个使用JADE进行混淆操作的例子。j筹麓燮戆掣||垂鬻繁;i+?lll蒸萋;;l{2《;ii;}蒸l,莉躐麟爹。谢黼嘲黧鳓黼蓦||||{:一i=i{};}¨萋瓣囊¨1j_≤ii…i薯誊蓦誊?ij㈡privateString0000000。o。。。000000000=nHello勇W。o“rld!t’;}:{}l善一羞_≯一蔓。。≯j10ublicstaticvoidmain(String}|args)}000000000000000000000000000000000000000000I;o00000000000000000000

Java类文件保护的埘f究及其实现浙江大学硕上学位论文同时又没有改变程序的逻辑,程序的运行结果没有发生变化。人们很难读懂这段组合的替换还必须满足程序的基本要求,即函数和变量名必须以字母开始,所以对上面已经混淆的代码再一次进行混淆[36】,由于jmangle并不知道是否是混淆灞蔷瀵满鞴蘩鬻瓣鬻iiiii}|。辫}j|+ii篓i誉蒸ii篆攀篱_____萎iiiii^:囊攀阏jman臻gile囊Y,;蘩:]-Ji∽冀.{.E冀壤攀蘩黧蒸橐零鬻囊藜冀劳愿囊瑟蟹:。j誊囊曩;=;j薹菱褰;|;;;i二i一曩蠹。:ip叠『{哥曩|;;¨j量蠹叠誊t∥ij露撩{;{;|量量誊蓦、蓦i囊霉篓黪嘲i一誊童誊“|;_Ⅲ誊童誊;誊j…叠ji:∞誉誊董_∥量蛩。一囊j曩萎;{{誊曩羞{;||{÷-i蔓。privateStHngjm3=”Hello诵蕊纛董。“兰一_毒誊曩publici※stat]cvoidmai瓤String[]船g时%_:…0000000000000000000000000000000000000000000;ooOO00000000000000006Java类文件保护的训f究及其实现浙江大学坝+学位论文使用了jmangle对已经混淆了一次的代码再次进行混淆后,代码的可读性反而提高了。所以这种简单的字符替换的方式的保护强度是比较弱的。为了增加阅读的难度,可以在混淆时加入一些无用的代码到文件中,比如加入一些类的成员函数和变量。这些加入的成员函数和变量在程序中不会被引用,但是却可以起到很大的混淆作用。我们也应该看到混淆技术的局限性。由于混淆器不能够对关键字、字符串常量、引用的API函数、引入他人的包等一些关键的东西进行混淆,所阻就算过了混淆还是能够看到程序大致的框架,比如输出了什么字符,引用了哪些类,定义了哪些输出函数,调用了哪些本地函数等。随着混淆器技术的发展,除了这种简单的符号混淆之外,还出现了其他的一些混淆技术【16】:(1)防反编译技术。它利用反编译器的特点和漏洞来防止反编译。例如上面提到的Crema就是作者本人写的防Mocha反编译的软件。这种方法有时只能对某些反编译软件有效,而且一旦这些反编译软件做了修改也要进行相应的修改。(2)数据混淆。就是改变数据结构的存储和访问方式。比如把数组拆散成几个不相下的变量,把一个类拆成几个类等。(3)加入干扰的条件判断代码。这些条件判断代码不会改变程序的执行流程,只是增加了一些无用的判断。这种方法最为有效,也最为复杂,现在的大部分混淆技术研究都是针对这种方法展开的。这种方法对程序执行的效率又有一定的影响。代码混淆技术是目前比较流行和使用的类文件模糊技术。有一些专业的代码混淆器公司的产品已经非常出色,如果合理的使用这些工具就能对自己的产品起至0很好的保护作用。但是代码混淆也不是万无失的方法,事实上只要有足够的Java类文件保护的研究及其实现浙江大学硕士学位论文耐心,这些混淆了的代码还是可以反编译出来并且能够读懂的。2.4.数字水印技术由于Java类文件容易被反编译,从而导致对Java程序的未授权使用变得容易。所以在需要证明程序是否是非法使用时,数字水印就变得很重要。像在图片声音中嵌入水印一样,在Java程序中也能嵌入透明的、安全的和鲁棒性的信息。使用水印技术并不能阻止类文件被反编译,但是可以在需要确认某些程序是否属于剽窃时提供有效的证据。它可以有效地保证开发者对该程序的版权。嵌入的水印对程序的使用者来说是透明的,而对程序的开发者来说,可以轻易地找出未经授权的非法的程序使用[5】。根据水印的加入位置,数字水印可以分为代码水印和数据水印[6】。代码水印隐藏在程序的指令部分中,而数据水印则隐藏在包括头文件、字符串和调试信息等数据中。根据水印被加载的时刻,软件水印可分为静态水印和动态水印。静态水印存储在可执行程序代码中,比较典型的是把水印信息放在安装模块部分,或者是指令代码中,或者是调试信息的符号部分。和静态水印不同,动态水印则保存在程序的执行状态中,而不是程序源代码本身。在Java类文件中使用的是代码水印,同时也是一种静态水印。水印信息可以隐藏在类文件f包括常量池表、方法表、行号表)的任何部分中。在一般情况下,即使我们怀疑某个程序是剽窃的,我们也很难说谁是程序的原始作者,因为程序的剽窃者可能也会声称他才是程序的原始开发者。如果我们能在程序中嵌入代表作者身份的数字水印,那么在对被怀疑的程序进行验证时,我们就可以用水印解码的方法从程序中得到真正的作者的信息。然而数字水印技术也存在一些不足,比如需要插入额外的代码,需要仔细地编写哑函数及其调用,否则容易被有经验的反编译者识破,从而擦除水印。而且如果同时利用各种Java混淆器对带有水印的Java文件进行攻击,在有些情况下水印将失效。另外目前的水印算法在提供可靠的版权证明方面或多或少有一定的不完善性,因此寻找能提供完全版权保护的数字水印算法也是一个重要的课题【17】。Java类文件保护的研究及其实玑浙_2工大学硕士学位论文3.客户机应用程序的保护传统的保护方法虽然在一定程度上可以起到保护Java类文件的作用,但是都有各自的局限性和不足。本地编译虽然能很安全的保护Java类文件,但是它以失去Java的跨平台性为代价,而且其本地编译器的成熟性也有待提高,支持的复杂度也有待加强。代码隔离技术也能很安全的保护Java类文件,但是它只适用于B/S结构的Web应用程序,对客户机运行的应用程序就显得无能为力了;而且一旦应用服务器被攻破而使Java类文件泄漏出去,反编译后就可以看到所有的源代码。代码混淆技术使用的是类文件模糊技术,在重构技术日趋成熟的同时,只要有足够的耐心,这些混淆了的代码还是可以被反编译出来并且能够被读懂的。数字水印技术只是为了证明Java类文件的版权,而不能防止反编译。由此可见,传统的保护方法都不能很好的保护Java类文件。本文针对这种情况,提出了采用JNl(JavaNativeInterface)技术和定制ClassLoader技术相结合的方案来加密Java类文件。该方案的思想如下:(1)加密Java类文件:用c++实现的加密工具来加密Java类文件,加密后的Java类文件不是一种有格式的字节码文件,而是一堆乱码,因此反编译器对加密后的类文件是无能为力的。(2)替换启动程序:使用定制的启动程序来替换原先的MainClass来启动程序,但是并不需要修改已发布的应用程序的任何源代码,包括MainClass的代码。(3)使用定制的ClassLoader:在定制的启动程序中调用Class.forName0来替换虚拟机默认使用的SystemClassLoader,转而使用DecryptClassLoader来载入MainClass,因而被MainClass直接或间接引用的Java类都将被DecryptclassLoader载入。(4)使用JNI技术:在定制的DecryptClassLoader中查找并载入加密过的类文件,然后使用JNI技术调用本地动态链接库DecryptDll来解密类文件。6Java类文件保护的研究及其实虮浙江大学颁十学位论文?j二.”‘j‘;{|..?一j1。。。稿勘程序E_一甓j-j毫:?i鋈“jii誊薯j。i_-_i蒸-==囊i蔓叠囊蠹。;毒荔一‘o遴萝i;}{!。甏ii一能誊j:.jI≯一_蕞嚣---i;__。薹誊+;:挺曩j;。嚣:蓦≥i;}珏@溺鞠磷龋蠢娃≤瑟囊羹瀚蠢嘉黼飘瀛藕靛;:。鼍E攀黧;琴i:.|嚣錾≯j≯毒堇iii篓i攀.j.。;;藜ij篓j||1|||||||i。誉溺i溪l誊攀j糕ii餍i瀚I||!|垂i“s;蒸薹i,雾~i曩嚣~、…一。萋i蠢÷巨篓;__}{’.’l““|;。垂l㈣美m…{*_|}_l‘薯’__㈣=_=_=;=≈图3客户端应用程序的保护方法如果要使用该方案,就需要对已经发布的应用程序进行加密:(1)用加密工具来加密已经发布的Java应用程序;(2)增加定制的DecryptClassLoader类到加密后的Java应用程序中;(3)增加定制的BootApplication类到加密后的Java应用程序中;(4)修改Java应用程序的启动文件。加密的Java应用程序和加密前的应用程序的运行结果完全一致,具有如下几个特点:(1)安全性高:虚拟机在载入类的时候使用了定制的DecryptClassLoader,DecryptciassLoader载入的是加密的Java类文件,并使用JNI技术调用c十+实现的解密动态链接库DecryptDll来解密Java类文件。DecryptDll解密后返回的结果并不是正常的Java类文件,也不是Java类文件的字节流,而是相对应的java.1ang.Class对象。因为在DecryptDll的实现中也使用了JNl技术来凋用Java虚拟机的defineClass0函数,所以Class对象是由Java虚拟机创建的。因此,如果想要跟踪调试DecryptDll,就等于在跟踪调试.Java虚拟机,那是极其困难的。(2)改动小:在不需要修改已经发布的应用程序源代码的情况下就可以对应用程序进行加密和解密工作。(3)移植性好:DecryptDll是用标准的c++来实现的,所以在各个平台上都能很好的编译,达到了代码级上的兼容。

Java类文件保护的研究及其实现浙江人学碗上学位论文因此,该方案具有安全性高、改动小、移植性好等优良特性,本章节将详细讨论该方案在客户机应用程序的实现原理及其过程,至于服务器应用程序将在下一章节讨论。3.1.Java本地接口Java具有可以调用其他语言编写的程序的功能,这也就大大扩展了Java的功能。要让Java能够调用其他语言编写的程序,就得用到Java本地接口技术JNI(JavaNativeInterface)。它是一个本地编程接口,是JDK的一部分。通过JNI技术,Java就能够使用其他语言编写的代码,比如C++f13]。在以下情况下可能要使用到Java本地接口:(1)希望用更高效率的语言来实现对时间和效率有严格要求的模块。(2)希望Java能够访问旧代码或代码库。(3)希望一些关键的算法在本机代码中实现,这样就能够更好的隐藏程序的实现细节,起到保护的作用。可以看出,使用JNl技术的目的就是为了实现第三点提出的对我们的源代码进行保护,使他人不能够进行简单的反编译就能看到内部的实现。如果解密Java类的算法用Java语言来实现,那么实现这个解密算法的类文件是不可以被加密的,否则没有办法解密其他类。但是这个用解密算法类用Java来实现,类文件就很容易被反编译而看到解密算法的具体逻辑,最终会导致其他所有已经被加密的Java类文件都被解密。如果解密Java类文件的算法用c++来实现,如DecryptDll,那么这个本地代码库是很难被反编泽和调试的,其代码的安全性可以达到本地应用程序的安全强度。因此,解密算法用c++来实现,然后采用JNI技术来调用本地代码,其代码的安全性同样可以达到本地应用程序的安全强度。JNl技术的原理和实现部分可以参看JDK的相关文档和资料。下面是在Java代码中用JNI技术来调用C++实现的DecryptDll动态链接库的代码片断:从上而的代码中可以看到调用函数System.10adLibrary0是载入接下来所要Java类文件保护的耐|究及其实现浙fI‘大学硕士学位论文使用的动态链接库,这里载入的是具有解密Java类文件功能的动态链接库DecryptDll。decryptClass()接口是一个声明函数,其前面有一个native的函数修饰符,表明该函数是一个本地接口,其真正的实现是在本地代码DecryptDll动态链接库中。如果其他地方调用了该函数,那么虚拟机就会使用JNI技术在动态链接库中调用相应的接r]。定义好的decryptClass()接口的参数是加密后类文件的字节内容和该类文件所代表的类名,而返回值是java.1ang.Clsss对象。这里的返回值如果是byte[]或者是iava.io.InputStream,那么当虚拟机在使用JNI技术调用本地代码的时候,返回值很有可能被第三方工具截留并保存下来,如果这些返回值是解密后的类文件的数据,那么该接口是极其不安全的。如果接口的返回值是java.1ang.Class对象,那么第三方工具即使截留也是没有意义的,因为返回值已经是形成好的对象,从对象内只能看到该对象当前的一些状态,其他任何信息都看不到。因此,返回值是iava.1ang.Class打消了第三方工具截留虚拟机调用本地代码时返回值的可能性,加强了虚拟机和本地代码通信的安全可靠性。在Java中定义好使用的本地接口之后和实现具体的本地代码之前还有一件事情必须要做,那就是制作本地代码的头文件,该头文件是本地接口所要实现的头文件[29】。由于Java本地代码的头文件和普通的头文件格式不同,所以要使用JDK里的工具来生成这个头文件,方法是在编译完成上面的代码以后执行javah命令。这样就会生成一个.h的文件,里面有这个本地函数的声明。_|d目两瑚,j|1:螺,隰豫醚《INICAH4蓦姆l灏瓣毒i蓐薯静稿eA)ec萝I.谨(&s鼗臼麟蟾曩培蹦蝤taivjE从上面的头文件I一,以看到和普通的头文件的差别。这里引用了文件<jni.h>,它是JDK自带的文件,在JDK的include目录下,如果c++语言的丌发环境没有设置,这个目录将会编译不通过。生成了头文件以后就可以升始编写函数的实现代码了。Java和本地代码相结合可以提高Java的安全性,但是Java作为--;foo可以跨甲台而设计的浯言,一日.结合了本地代码,它的跨平台的特性就要受到影响。如果本地代码使用标准c++编写,除非只在‘个平台上使用,或者在里面不要引用任何与平台相关的APl函数,这样在另外的平台卜只要进行一次编译就能够运行,于是本地代码也就能够实现基本的代码级的兼容。在本文的解决方案中,用Java类文件保护的研究及其实现}l『i江大学硕士学位论义C++实现的DecryptDll就是用标准C++来编写的,并没有调用和平台相关的任何API,在各个平台』i都J1r以顺利的编译通过,因此能够完全实现代码级上的跨平台性。3.2.定制ClassLoaderClassLoader是Java虚拟机的类文件加载器,专门用来载入虚拟机所需要的类。Java虚拟机把要装入的类名告诉ClassLoader,在默认情况下,虚拟机使用的是SystemClassLoader,SystemClassLoader根据CLASSPATH环境变量设置的值或者是在运行iava命令的时候通过一classpath参数传入的值来查找类,并读入找到的类文件数据,然后把它转换成一个Class对象并交给Java虚拟机去运行[14】。在Java虚拟机中,各个ClassLoader对象是按层次结构组织的,除了最顶层的BootstrapClassLoadcr以外,每一个ClassLoader对象都有一个ParentClassLoader。这种父子层次结构的组织关系是建立在调用(Calling)关系的基础上,而不是建立在各个ClassLoader类的继承关系上。在创建一个CtassLoader时,如果没有显式地给出ParentClassLoader,那么虚拟机将默认SystemClassLoader为其ParentClassLoader。下面这个图就是在Java虚拟机内部的ClassLoader层次组织图,最顶层的是BootstrapClassLoader,负责从JRE中查找并载入需要的类。下面的SystemClassLoader则是根据CLASSPATH环境变量设置的值或者是在运行iava命令的时候通过。classpath参数传入的值来查找并载入需要的类。下的几个Ax和Bx都是定制的ClassLoader,可以自定义从各个地方载入所需要的类,如从远程的网络上下载并载入到本地的Java虚拟机中。Java类文件保打-的研究及其实现浙旺大学硕士学位论文图4ClassLoader的层次结构Java虚拟机载入类的模型是一种代k翌(delegation)模型。当虚拟机要求当前的ClassLoader载入一个类时,ClassLoader首先将这个类载入请求转发给他的ParentClassLoader。如果ParentClassLoader已经找到并载入了这个类,那么当前的ClassLoader就没有必要继续去查找这个类了。只有当ParentClassLoader没有载入这个类时,当前的ClassLoader刁‘获得载入这个类的机会。3…21为什么要定制ClassLoader在一般情况下,Java开发人员在编写Java程序的时候不需要任何ClassLoader的相关知识,凶为Java虚拟机在默认情况下都是使用SystemClassLoader来载入所需要的类,而且在代码中也不会出现和ClassLoader有关的代码。但是SystemClassLoader的功能有限,它只能根据CLASSPATH环境变量设置的值或者是在运行iava命令的时候通过.classpath参数传入的值从本地硬盘装入类文件。Java作为一种面向刚络的语言希望能够从网络上获取类文件来执行,如Applet就是使用定制的NetworkClass[。oader从网络L载入所需要的类文件。除此之外,还叮以定制ClassLoader来实现一些附加的功能,LINCH验证类文件的来源可靠性等。在本文巾,将定制一个ClassLoader米解密已经被加密的类文件。Java类文件保护的研究及其实现浙江大学硕十学位论文3.2.2.定制ClassLoader的方法在Java中,java.1ang.ClassLoader类是…个抽象的类,要定制自己的ClassLoader类,就必须继承这个抽象类并实现其巾的几个方法。ClassLoader类中的的loadClass()力法默认是调用findClass()方法,findClass()方法去查找指定的类。所有的定制ClassLoader都应该继承自java.1ang.ClassLoader,并实现其中的findClass()方法1271。以下是loadClass()的实现步骤;(1)调用findLoadedClass()方法查看类是否已经存在,如果已经存在则返回找到的类;(2)读入类文件到一个byte型数组的缓冲区罩;(3)如果有类文件则把缓冲区里的数据通过defineClass()方法定义一个类对象;(4)如果没有类文件则调用findSystemClass()方法从系统获得类;(5)如果没有类,则返回ClassNotFoundException异常;(6)如果resolve为true则调用resolveClass()方法解析class对象;(7)返回类。这里最关键的步骤就是调用defineClass()这个方法。它的作用是把一个byte型的数组定义成一一个类对象,原型为:protected最n瓤毒囊鞲彝秘n薯ei舔鬓隧孽薹i奄,intoi;f;:证t诗翥;lhf。讲羲薹瞄§i薹矗rmatE玎西…■Ⅲ参数b是byte数组舱缓弹区,照酉存放的是类文件的内餐蔓i一i¨『¨。一参数off是by蟪裁缀:的起始偏秽毒曩。¨一t曩量};;;}};j;};:::;蠹弧参数ien是by:c。.≤g缫斡长度童堇==_3.2.3.实现DecryptClassLoaderDecryptClassLoader是本文定制的一个Class[。oader类,它可以在载入类文件的时候自动解密已经被加密的类文件。在解密类文件的时候,使用JNI技术来调

Java娄文1;_|=保护的研究及其实现浙江人学硕上学位论义用本地动态链接库DecryptDll,其中的解密算法都是采用c++实现在DecryptDll中。其中关键的代码片断如下:while(true){量。_…_i■_’==j:≯≥|。薯。=int§}_l|b3isxead[enClassB}’teSreadefliength?readed瓣Java类文件保护的研究驶其实现浙江大学硕士学位论文在本方案中,定制的ClassLoader类DecryptClassLoader类是不可以被加密的,一旦这个类也被加密,那么就没有类呵以解密应用程序中的类文件了。因此,在Decryptc】assLoader类巾就不能实现具体的解密类文件的算法,而是采用JNI技术调用DecryptDll本地动念链接库中的decryptClass()方法来解密类文件,具体的算法实现在DecryptDll动态链接库中。因此,在DecryptClassLoader中没有任何与解密有关的算法实现,即使被成功的反编译,也没有任何可用的解密信息,所以该类可以不被加密的。用c++编写的DecryptDll动态链接库实现了具体的解密类文件的算法,要破解其中的算法是及其困难的,因此,DecryptClassLoader的安全强度是非常可靠的。定制的DecryptClassLoader类实现了findClass()方法。在查找要解密的类文件之前,首先需要检查类文件名称的前缀。因为Java的开放性,目前在Java领域有丰富的丌源库,有些己经成为实施上的标准,如用来记录日志的_,具l094j库,该库所有的类名称都以前缀“org.apache.1094j”打头,用柬标识和区别其他类库。唰样,Java自带的类库都是以“java”和“iavax”打头,也是用来区别其他类库。这些第三方类库和Java类库都是没有加密过的类文件,是正常的类文件。因此,这些类文件就不需要经过任何与解密有关的操作,DecryptclassLoader类只需按照SystemClassLoader类的奄找路径就可以,即调用Parent来载入类。加密过的类文件已经不是一常的类文件,因此其不能以扩展名为.class命名,ClassLoaderJava类文件保护的研究及其实现浙姐大学顸士学位论文否则SystemClassLoader会认为找到的类文件不是一个有效的类文件,因此,本文把加密后的类文件扩展名改为.class2。其实加密后的类文件对于虚拟机来说,已经不是一个类文件,只是一个普通的文件。在DecryptClassLoader类中,把加密后的类文件当作一个资源文件来处理,在程序中调用getResourceAsStream()方法读入加密后的类文件,形成一个InputStream的二进制流。实际上,getResourceAsStream()函数载入资源的方法和SystemClassLoader载入类文件的方式足一致的。把加密后的类文件以二进制流的形式读入内存,形成byte型数组。然后,DecryptClassLoader类就把byte型数组和类名传给本地接口decryptClass来解密并返回Class对象,而不是正常的类文件的二进制流。在下面的章节中可以看到,DecryptClassLoader类是在定制的启动程序中被使用并创建对象的,启动程序首先用DecryptClassLoader对象来载入并解密应用程序的MainClass,应用程序中所有其他的类都是被MainClass直接或间接的引用,因而这些被引用的类都会采用DecryptClassLoader来载入并解密。3.3.加密及其解密3.3.1.加解密库的实现在本文的方案中,为了保持加密和解密算法的统一性和一致性,采用了同一种语言c++来实现。在算法库中主要定义了两个接口:boolEncryp嫡1e(ch禚szsoi托em,char?iszDestinati0藤i_le);董:¨:第一个接口DecryptClassl,oader_decryptClass()是用iavah产生的本地接口,是给DecryptClassLoader类中使用JNI技术来调用的,在本章第二节已有叙述。第二个接VIEnery口tFilc是用来给加密工具调用的,其第一个参数是正常的java类文件的路径,第二个参数是加密后的java类文件的路径。在具体的算法实现上,我们采用了DES算法来加密和解密类文件。DES是美国国家标准局1973年开始研究除国防部外的其它部门的计算机系统的数据加Java类文件保护的副f兜及其实现浙江大学坝十学位论文密标准,该加密算法具有如下特点f7]:(1)提供高质量的数据保护,防止数据未经授权的泄露和未被察觉的修改;(2)具有相当高的复杂性,使得破泽的开销超过可能获得的利益,I司时又要便于理解和掌握:(3)DES密码体制的安全性应该不依赖于算法的保密,其安全性仅以加密密钥的保密为基础:(4)实现经济,运行有效,并且适用于多种完全不同的应用。DES算法的实现在网上已经有很多,这里不多叙述。下面是在c++代码中解密类文件并使用JNI技术调用虚拟机中的defineClassO方法的代码片断:从上面的代码中可以看到,首先用DES算法解密己经被加密过的类文件数据,生成原始的类文件数据。但是接口并没有把原始的类文件数据直接返回,而是又调用了Java虚拟机中的defineclass()方法,把原始的类文件数据定义成一个Class对象后再返回。这样,就避免了Java虚拟机和本代代码厍通信时原始的类文件数据被窃取的可能性,保汪Java类文件的安全性。3.3.2.加密工具的制作加密工具是用来加密Java类文件的专门1:具,当然加密工具也支持其他文件的加密。工具在加密后删除原先的Java类文件,生成新的加密后的Java类文件。为了防止DecryptClassLoader把加密后的Java类文件定义成无效的Class对象,加密后的Java类文件应该使用不同的文件扩展名,如.class2。这样,DecryptclassLoader就不会把加密后的文件作为一个类文件来处理,而是把其视为一个普通的文件资源。卜图是Java类文件的加密流程:Java类义件保护的酬究及其实虮浙江大学顾扛挲位论文t3善…一川。_≥j?。羞|:?’:)};};|};|囊囊箱密『【真;{|;:誊iI曩曩薹¨_{_=曩。:氆薹鬟;j;¨¨,:iⅫ蛩叠嚣i||||}蒸iiii豢豢攀ii图5加密工具加密.class文件通常情况下,在发布的Java应用程序中Java类文件都被打包成.jar的压缩包文件中。因此,加密工具应该支持包文件.jar文件的加密,其内部具有解包和打包功能。下图是包文件.jar文件的加密流程:i攀蒸i黍粪;?薯|||i||u蒸黍:j。瞵冒。。=.。二凰j.圈蛩ii攀i擎鬻寨黧洋ii垂墓||纛烈…i2i;睑篓黧攀i、黧熬辫==。墨i爱i~鬻蒸;};||||||}|}|藩i黧蒸_j『;-}-曩j纛I___}i一l誊l担到i;i;黧划叫删图6加密工具加密.jar文件在Java领域,Ant已经成为编译、打包、测试以及部署的标准工具[191。现在虽然已经有了许多的build工具,例如make、gnumake、nmake、jarn等,而且这些工具都非常优秀。Ant之所以流行,在某种程度上和Java一样,因为Ant也是一个跨平台的build工具。之所以Ant能跨平台,是因为Ant本身包是用Java来编写的,而且Ant不需要编写复杂的shell命令,只需要一个XML配置文件,就可以定义并运行各种各样的任务,任务的运行是由实现了特定任务接口的对象来完成的。为了能将加密工具无缝集成到Ant工具中,本文将加密工具实现成‘个Ant任务,这样就可以充分利用Ant中已有的解包和打包工具[251。使用Ant工具时,需要编写build配置文件,下面是build.xml文件中一个AntTarget的例子:

Java类叟件保护的研究及其实现浙江大学硕士学位论文在encrypt这个AntTarget中,“cn.edu.zju.classloader.Encrypt”是实现的Ant任务类,在这里已经被定义成一个名为“encryptclass”的Ant任务。然后encryptclass任务就会去加密安装目录下类名以“cn/edu/zju”打头的所有类。3.4.定制的启动程序这里的启动程序是一个BootApplication类,该类的作用就是替代已经加密过的MainClass来启动已经加密过的Java应用程序。该类和DecryptClassLoader类一样,是不能被加密的,否则就没有类呵以启动已经加密过的Java应用程序了。而且BootApplication类的内部实现中也没有和任何加解密有关的信息,即使被成功反编译也是没有意义的。下面是BootApplication类的具体实现代码:pub№滴蠢6黉辫辫喾i?ii{|{|{|{_{_蓦¨|萋誉jiI¨≤{|;__j:;j_:I誊i≥ipublicstaticvoidmain(Stringargs[])StringmainClassName=args[0]:j_i曩.i誊iii善{}{i≯薯曩l{I∥这些是传递貔藏用零身的参数StringjrealArgs[]。FlEWString[args.Iength-t》曩曩_|:|;囊。_if(args:length-t蔫o){『。。。。叠■一j曼墨量1_=__曩薯System.array90py(args.1,realArgs,0,args.1eogth一磁卜tryf。_:-囊j≯蔓iDecryptClassLoaderJava娄文件保护的研究及其实地浙江大学硕士学位论文DecryptClassLoad铆臻学tApplicac啪。cIass.geIclaSsLoade“))从代码中可以看到BootApplication类也是一个MainClass,是一个可以启动并运行的Java类。在BootApptication类中首先保存传入给真正应用程序的MainClass参数,以便在解密生成真正的MainClass后,可以把保存好的参数传给它。BootApplication类首先创建一个DecryptClassLoader对象,用该对象来载入真正的MainClass类,这其中使用了关键的Class.forName0方法。正是因为该方法的使用,才会引起一系列的连锁反应:其他被MainClass直接或间接引用的类都将通过DecryptClassLoader对象载入,需要解密操作的就调用decryptClass(1本地接口来解密,第三方类库或者JRE自带的类就交给SystemClassLoader来载入。这些逻辑在DecryptClassLoader类中都已经实现了。在BootApplication类中成功的载入MainClass类之后,使用了iavareflect相关技术来调用真正的Main()启动函数,并把保存好的参数传入该Main()区J数。在发布的Java应用程序中,为了方便启动,Java应用程序的启动程序…般是一个脚本文件,用来自动执行复杂的命令行。在windows系统下,通常是.bat文件;在linurdunix系统下,通常是个,sh文件。为了适应新的启动程序类,需要修改这个脚本文件。具体该法如下,这里以windows上的bat文件为例:j//发布叫提供的脚本文件。d~“……”j!i=“々“■一‘=一?一一_一iavaHelloWorld-Dnamet=valuel一Dnanle2=value2:y,*Java类文件保护的研究及其实现浙江大学硕士学位论文脚本的修改非常简单,只需把上述的MainClass(在例子中是HelloWorld)修改成BootApplication类,并把MainClass的类名及其传入的执行参数都作为BootApplication的执行参数传入,如r:从上面可以看到,启动程序的制作是非常简单的,只需加入一个BootApplication类,并简单的修改启动脚本就可以启动已经加密过的Java应用程序了。3.5.本章小结采用JNI(JavaNativeInterface)技术和定制ClassLoader技术相结合的方案来加密Java类文件,可以从根本上解决保护Java类文件的问题。发布的Java应用程序如果需要保护其中的Java类文件,不需要任何改动就可以进行加密。加密工具与Ant的集成,可以在一发布应用程序就进行自动加密,方便了应用程序的测试与部署。加密后的应用程序采用JNI技术来调用本地代码,其所有的加密和解密算法都实现在本地的动态链接库中。如果黑客想窃取Java源代码,就不得不首先反编译用C++编写的动态链接库,其难度是非常大的。因此,加密后的Java应用程序的安全强度可以达到本地应用程序的安全强度。解密中使用的本地动态链接库采用标准的c++来实现,没有使用与平台相关的API函数,所以在各个平台上都可以顺利的编译通过。因此加密后的应用程序可以在各个平台}=运行,达到代码级上的兼容性。本章节详细讨论了客户机应用程序中Java类文件的保护方法。下一章节将详细讨论服务器应用程序中Java类文件的保护方法。Java类文件保护的研究及其实现浙江大学硕上学位论文4.服务器应用程序的保护上一章节讨论了客户机应用程序中Java类文件的保护方法,在这一章将讨论服务器应用程序中Java源代码的保护方法。服务器应用程序是一种B/S结构模式的应用,这些应用程序都部署和运行在一个Java应用服务器上,如ApacheJakartaTomcat,BEAWebLogic和IBMWebSphere等Java应用服务器。本文将以开源的ApacheJakartaTomcat做为应用服务器的例子,在其上所采用的有关Java类文件的保护方法也同样适用于其他Java应用服务器。4.1.J2EE和Servlet/JSPJ2EE(Java2Platfoi'mEnterpriseEdition)是一种利用Java2平台来简化企业级应用程序的开发、部署和管理相关的复杂问题的体系结构。J2EE不仅巩固了J2SE(Java2PlatfomlStandardEdition)中的许多优点,例如“编写一次,到处运行”的特性,同时还提供了对Servlet/JSP,EJB,Ⅺ订L/webService技术的全面支持,其最终目的就是要提高企业级应用程序的开发效率,缩短开发周期[30]。J2EE使用多层的分布式应用模型,应用逻辑按功能划分为组件,各个应用组件根据他们所在的层分布在不同的机器上。事实上,Sun设计J2EE的初衷jF是为了解决两层模式(client/server)的弊端,在传统模式中,客户端担当了过多的角色而显得臃肿,在这种模式中,第。次部署的时候比较容易,但难于升级或改进,可伸展性也不理想,而且经常基于某种专有的协议一一通常是某种数据库协议。它使得重用业务逻辑和界面逻辑非常困难。现在J2EE的多层企、啦级应用模型将两层化模型中的不同层面切分成许多层。一个多层化应用能够为不同的每种服务提供一个独立的层,以下是J2EE典型的四层结构[281:Java娄文件保护的研究及其实现浙江大学硕士学位论文图7J2EE框架(1)运行在客户端机器上的客户层组件:应用客户端程序和applets:(2)运行在J2EE服务器上的Web层组件:JavaServlet和JSP(JavaPage):Servlet(3)运行在J2EE服务器上的业务逻辑层组件:EJB(Enterprise(4)运行在EIS服务器上的企业信息系统(Enterprise库系统,和其它的遗留信息系统。JavaBealls):InformationSystem)层软件:包括企业基石出建设系统例如企业资源计划(ERP),大型机事务处理,数据J2EE的w曲组件既可以是JavaServlet也可以是JSP页面。JSP页面也是Servlet,它的出现只是可以更方便地建立静态内容。Servlet是~种小型的、与平台无关的Java类,被编译成跨平台的字节码后,这种代码就可以动态地加城到个Web服务器上,并由此Web服务器运行。Servlet通过|干十由Servlet容器实现的请求一响应模型与Web客户机进行交互。这种请求.响应模型建立在超文本传输协议(XTTP)行为的基础之上。很长~段时间,公共网关接口(CGI)程序(常被称为CGI脚本)~直是开发动态交互页面的首选,并不断推动着Web的普及。但JavaServlet可以以更高的效率釉可移植性寐实现这一目的,因而可望最终取代CGI程序。JayaSe川et的出现,为程序员使用Java来创建Web应用程序开辟了新的途径。CGI应用程序本身往律不是完整的应用程序,在处理接收来自Web浏览器上用J、t的信息请

Java类文件保护的研究及其实现浙“大学顶十学位论文求时,CGl只是整个处理过程中的个中间步骤。例如,CGI应用程序的一种常见用途是访问数据库。将它用丁这种任务时,CGI程序提供一种方法,将用户的数据请求连接到能满足这种请求的企业数据库。CGI程序常常充当‘种中间软件,从Web浏览器接收请求,决定必须调用哪些计算资源来满足这些请求,并向浏览器发回响应。JavaServlet与CGI程序一樽,最适合充当连接前端Web请求与后端数据资源的中间层组件。4_2-Tomcat介绍Tomcat是一个免费的开源的Servlet容器,它是Apache基金会的Jakarta项目中的一个核心成员,由Apache,Sun和其它一些公司及个人共同开发而成。由于有了Sma的参与和支持,最新的Servlet和JSP规范总能在Tomcat中得到体现。Tomcat被JavaWorld杂志的编辑选为2001年度最具创新的Java产品,可见其在业界的地位。Tomcat最薪版本是5.5。从版本4,0x开始,采用了与以前完全不同的架构,并重新设计了Servlet容器:Catalina,完整的实现了Servlet2.3和JSPl.2规范。Tomcat提供了各种平台的版本供下载,可以从http://jakarta.apache.org上下载其源代码版或者二进制版。本文中所使用的Tomcat版本是4.1.3。由于Java的跨平台特性,基于Java的Tomcat也具有跨平台性。与传统的桌面应用程序不同,Tomcat中的应用程序是一个war(WebArchive)文件。War是Sun提出的一种Web应用程序格式,与JAR类似,也是许多文件的一个压缩包。这个包中的文件按一定目录结构来组织:通常其根目录下包含有HTML和JSP文件或者包含这两种文件的目录,另外还会有一个WEB—INF目录,这个目录很重要。通常在WEB—INF目录下有一个web.xml文件和一个classes目录,web.xml是这个应用的配胃文件,而classes目录下则包含编译好的Servlet类和JSP或Servlet所依赖的其它类(如JavaBean)。通常这些所依赖的类也可以打包成JAR放到WEB.INF下的lib目录下,当然也可以放到系统的CLASSPATH中,但那样移植和管理起来不方便。在Tomcat中,应用程序的部署很简单,只需将War放到Tomcat的webapp目录下,Tomcat会自动检测到这个文件,并将其解压[18]。Tomcat不仅仅是一个Servlet容器,它也具有传统的Web服务器的功能:处理HTML页面。但是与Apache相比,它的处理静态HTML的能力就不如Apache。我们可以将Tomcat和Apache集成剑一块,让Apache处理静态HTML,而Tomcat处理JSP和Servlet。这种集成只需要修改一下Apache和Tomcat的配置文件即Java类义件保护的研究及其实虮浙江人学硕上学位论_丑:可。4.3.ServletContainer和Servlet的关系4-3.1.什么是ServletServlet是一个以Java技术为基础的Web组件,它被Servlet容器管理,能产生动态的内容。像其它以Java为基础的组件一样,Servlet是独立于各种平台的Java类,它能够被编译成平台独立的字节码,然后可以在含有Servlet容器的Web服务器上装载和运行。Servlet容器有时也被称作Servlet引擎,是Web服务器的扩充,它提供了Servlet的功能。Servlet通过Servlet容器实现的请求/应答机制与Web客户端进行交互[3l】。Servlet与Web服务器的关系类似于Applet与Web浏览器的关系(这也是为什么Servlet技术被称为Servlet的原因),我们可以将Servlet想象成没有前端界面(faceless)的Applet。与Applet不同的是,由于Servlet运行在Web服务器端,因此它是一个可信赖的程序,不受到Java安全性的限制,拥有和普通Java应用程序一样的权限。Servlet是CGIScript的一种替代技术,由于Servlet在性能、可移植性、代码重用等方面比CGI具有显著的优势,因此在未来的技术发展过程中,Servlet有可能彻底取代CGI。4.3.2.Servlet接口的定义l瓣◆Java类文件保护的研究及其实现浙7t大学倾十学位论文协议,所以在J2EE规范中,也同样定义了HttpServlet接口,它扩展了Servlet接口并增加了如下几个方法:在HttpServlet中增加的接口方法都是基于HTTP具体协议中使用的方法,如最常用的GET、POST等方法。在实际编写具体Servlet的时候,都是扩展了HttpServlet接口,而不是Servlet类,除非使用了非Http协议。在HttpServlt接口中,最重要的是doPost();}'fldoGet()方法。这两个方法都是根据数据是通过GET还是POST发送,再调用对应的doGet().和doPost()方法。4.3.3.什么是Servlet容器Servlet容器是Web服务器或应用服务器的”‘部分,它提供了网络服务。通过这些网络服务请求和应答对以MIME为基础的请求进行解码,MIME为基础的应答。一个Servlet容器能够建立在Web服务器的核心中,也一可以通过服务器本身的扩展API作为附加组件安装在一个Web服务器中。Servlet容器还可以嵌入或安装到支持Web的庸用服务器中。所有的Servlet容器必须将HTTP作为请求并形成以和应答的协议。另外,以类似ttTTPS这样的协议为基础的请求和成答也可以被支持。Servlet容器负责处理客户请求、把请求传送给Servlet并把结果返回给客户。Java类文件保护的研究及其实现浙江大学硕士学位论文不同程序的容器实际实现可能有所变化,位容器与Servlet之间的接口是由ServletAPI定义好的,这个接口定义了Servlet容器在Servlet上要调用的方法及传递给Servlet的对象类。一个Servlet容器可以具有这样‘个处理序列[39]:(1)一个客户端连接到一个Web服务器,并发送一个HTTP请求到这个Web服务器。(2)请求被Web服务器接收,并转交给Servlet容器。Servlet容器可以与Web服务器在同一个主机上运行或者是不同的主机上运行。(3)Servlet容器在其配置的Servlet中找到调用的Servlet,然后,用代表请求和应答的对象调用它。(4)Servlet完成已经被编入程序的处理逻辑,然后生成数据返回客户端。在它将数据返回到客户端的时候通过应答对象完成。(5)当Servlet完成了对请求的处理,Servlet容器确认应答已经确实完成,则将控制权返回给Web服务器。容器在Servlet首次被调用时创建它的一个实例,并保持该实例在内存中,让它对所有的请求进行处理。容器可以决定在任何时候把这个实例从内存中移走。在典型的模型中,容器为每个Servlet创建一个单独的实例,容器并不会每接到一个请求就创建一个新线程,而是使用一个线程池来动态的将线程分配给到来的请求,但是这从Servlet的观点来看,效果和为每个请求创建一个新线程的效果相同。下面这个图便是Servlet容器创建Servlet的顺序图。生兰茎茎壁!塑塑塑墨茎薹翌塑坚查堂堕主堂些丝兰图3Serlet容器管理Servlct的模型4.3.4.Servlet的生命周期Servlet需要运行在支持Servlet容器的Web服务器上,例如Tomcat。因此,Servlet容器管理着Servlet的生命周期,负责Servlet的加载、初始化、接收请求、响应请求、以及销毁等工作在代码中,Servlet生命周期由接口javax.servlet.Servlet定义。所有的JavaServlet必须直接或间接地实现javax.servlet.Servlet接口,这样才能在Servlet容器中运行。javax.servlet.Servlet接口定义了一些方法,在Servlet的生命周期中,这些方法会在特定时蒯按照一定的顺序被调用[24】。如图14—1所示。S8结柬8etyler对应8erFle_睹勺destroy方法容器装载8ercletE幢Servlet宴例扔始化Serdet对应ScaleH拘init方法调用se州ce方浩对应Servle韵service方法图9Servlet的生命周期(1)Servlet的加载(Loadl

本文来源:https://www.bwwdw.com/article/w907.html

Top