网络安全

位置:IT落伍者 >> 网络安全 >> 浏览文章

解析Java体系结构对信息安全的支持


发布日期:2024年08月15日
 
解析Java体系结构对信息安全的支持

Java语言拥有三大特征平台无关性网络移动性和安全性而Java体系结构对这三大特征提供了强大的支持和保证本文着重介绍Java体系结构对支持信息安全的原理和使用方法

Java体系结构

Java的体系结构如下图所示首先Java的源代码Java文件由编译器编译成Java的二进制字节码class文件然后class文件由Java虚拟机中的类装载器进行加载同时类装载器还会加载Java的原始 API Class文件类加载器主要负责加载连接和初始化这些class文件以后就交给虚拟机中的执行引擎运行执行引擎将class文件中的Java指令解释成具体的本地操作系统方法来执行而安全管理器将在执行过程中根据设置的安全策略控制指令对外部资源的访问

Java的执行方式不是编译执行而是解释执行不同平台上面相同的源代码编译成符合Java规范的相同的二进制字节码然后再交给支持各自平台的虚拟机去解释执行先编译后解释再执行三步走的方式使得Java实现了一次编写到处运行如果Java应用使用的是%标准Java API并且没有直接调用本地方法那就可以不加修改地运用在多种平台上这样的平台无关性使得在异构的网络环境或者嵌入式方面的应用更方便和现实Java的网络移动性带来了一种全新的软件模式在分布式处理模式的基础之上可以将软件和数据通过网络传送到客户端去这样确保了客户端有必备的软件来浏览和操纵通过网络传输的数据Java体系结构支持把单一的执行文件切割成小的二进制字节码文件Class文件而这些文件可以按照应用的需要动态连接动态扩展Java体系结构对安全性的支持主要是通过Java语言本身安全性虚拟机的类加载器和安全管理器以及Java提供的安全API几个方面来实现防止恶意程序的攻击程序不能破坏用户计算机环境防止入侵程序不能获取主机或所在内网的保密信息鑒别验证程序提供者和使用者的身份加密对传输交换的数据进行加密或者给持久化的数据进行加密验证对操作设置规则并且进行验证

Java信息安全的必要性

随着互联网应用越来越广泛并且互联网其本身独特的资源共享性因此能够按照用户需求及时准确获得信息和处理信息的应用对用户而言就相当重要这也是Java得以迅速发展和被广泛接受的原因但同时网络也提供了一条攻击接入计算机的潜在途径特别是当用户下载网络软件在本地运行这就要求Java能够对病毒/木马的问题加以防范对信息以及本地环境进行保护比如我们浏览一个网页的时候网页上的Applet可能会自动下载并且运行而这个Applet完全有可能来自不可靠的地方又或者我们使用通过JINI服务查找到的网络上不可靠的服务对象来获得服务如果没有Java体系结构提供的安全机制这就很有可能引入了一个怀有敌意的程序造成信息丢失资料洩密相信伪造数据和修改本地计算机安全设置等等后果带来未知的严重后果

Java语言本身安全性

Java语言的设计者们是在C++的基础上设计出来Java的因此与C++相比它的语法更加简单清晰结构单元运算符重载虚拟基础类等在Java中都没有采用并且取消了多重继承而采用实现多个接口的方式这样能降低开发人员犯错误的几率帮助他们写出更安全的代码

Java中去除了C++语言中的令人费解容易出错的指针用列表哈希表等结构来代替避免了任何不安全的结构Java也没有索引核查的数组访问因为这往往会导致不定的不可预测的程序操作它所有的数组访问都必须先检查是否越界Java要求所有的变量在初始化以前不能使用对于基本数据类型变量都会自动地赋给某个初始值避免了未初始化变量获取内存信息所有这些都使得程序不能访问任意的内存地址对于内存中的实体信息只能通过有权限的对象进行访问而不会出现象C++那样把类型指针强制转换成内存的指针然后通过内存查找的方法找到私有的变量

Java分配内存对于开发人员来说是透明的开发人员使用new方法新建对象这时候虚拟机就会从堆内存中找到合适的内存空间开发人员不需要也不能够进行干预而对于内存的回收Java避免了开发人员明确干预对象的回收比如C的free或C++的delete命令避免了开发人员无意间对内存的破坏Java采用虚拟机的垃圾回收机制来实现的内存自动管理释放不再被使用的内存资源内存回收器就像一台垃圾收集车但是和我们在大街上看到的收集车仅仅收集大家放在垃圾桶里面的垃圾不同的是它还要到你家里去帮你找出那些东西是不要用的垃圾然后把这些东西拿走最后还要整理家里的空间腾出最大的空间让你放新东西Java的内存回收器目的就是找到不再引用的对象释放内存空间并且需要整理内存的碎片空间尽量避免出现内存不足的情况

对于在网络中交换的序列化对象很容易在重建对象的时候访问到对象的私有信息这时候Java提供了两种办法来保护信息一种就是采用给变量加上transient关键字的方法这样对象序列化的时候就不会读写该变量另一种就是在实现Externalizable接口而不是Serizlizable接口这样对象就只能通过writeExternal和readExternal方法来保存和重建其他方法无法进行了

以上这些都是Java语言本身对信息安全提供的基础

类加载器

虽然名字叫类加载器但是实际上Java虚拟机中的类加载器不光要负责加载而且要负责连接和初始化应用程序需要用到的Java类型加载就是把二进制形式的字节码读入虚拟机中而连接就是给这个已经读入的类型分配类变量内存以及把类型中用到常量池中的符号转换为直接引用最后的初始化过程就是赋给类型变量合适的初始值

类加载器为加载的类提供了不同的命名空间统一源代码生成的字节码被加载到同一个命名空间中相同命名空间不能加载类名相同的类同一个命名空间内的类可以直接进行交互而不同的命名空间的类是不能交互的除非显式地提供了交互机制通过命名空间和类成员访问权限的设置保护了被信任的类边界

类加载器分成了启动类加载器标准扩展类加载器路径类加载器和网络类加载器四种启动类加载器从本地系统中加载原始的Java API类用来启动Java虚拟机而其他三种加载器是在运行时加载用户定义的类标准扩展类加载器加载的是不同虚拟机提供商扩展的标准Java类而在classpath中的类由路径类加载器来加载网络类加载器加载通过网络下载得到的类文件每一种加载器在加载类的时候都会建立一个加载器实例类加载器采用双亲委派链模式(这个模式很类似GOF在《设计模式》一书中提到的责任链模式)除了启动类加载器以外每个类加载器都有自己的双亲一个类可以通过有三种方法定义自己的双亲第一种通过引用比如A类中引用了B类(即A和B有关联关系)那么B类的加载器就会作为A类的加载器的双亲早于A类加载第二种使用loadClass方法来自定义双亲这时被load的类的双亲即本身这个类加载器第三种在没有采用前两种的情况下使用的默认方式默认把启动类加载器作为双亲

在加载过程中当发出加载请求的时候加载器首先询问它的双亲――路径类加载器――来查找并加载这个类而这个加载器也向它的双亲请求加载一层一层请求上去直到启动加载器获得请求来查找并加载这个类如果这个类没有被加载并且查找不到返回结果给它的子加载器由子加载器加载直到请求返回给原来的加载器这时还没有加载成功的话由网络类加载器试图从网络中寻找并下载如果还不成功将抛出NoClassDefFoundError异常

这个过程保证了启动类加载器可以抢在标准扩展类加载器之前加载类而标准扩展类加载器又可以抢在路径类加载器之前加载类最后才由网络类加载器加载比如应用被试图加载一个带有恶意代码的javalangString类因为它本来是Java API的一部分它们加载到的命名空间可以得到被信任类的特殊访问权限但是由于启动类加载器是最早被加载的所以javalangString只会被启动类从Java原始的API中加载而带有恶意代码的javalangString类不会被加载进来这样有效的保护了被信任的类边界

类加载器中还包括了一个类型检查的功能模块它负责保证程序的健壮性它在类型的生命周期中要进行四次检查第一次检查是在加载的时候主要检查二进制字节码的结构首先格式要满足Java语言定义的规范然后要保证将要加载的类字节码是一组合法的Java指令第二次检查是在连接的时候主要是类型数据的语义检查保证字节码在编译时候遵守了规范比如对final类不会派生出子类也不会重载final的方法每个类只有一个超类没有把基本数据类型强制转换成其他数据类型第三次检查也是在连接的时候关注于指令的结构保证指令的操作数类型和值正确操作数堆栈不会出现上溢出或者下溢出最后一次检查在动态连接的时候主要检查类型中的符号引用被解析时是否正确以上的问题都会产生恶意的行为所以必须在运行前进行检查而一部分检查工作会在虚拟机运行字节码的时候检查比如数组越界对象类型的转换等等一旦检查发现了问题就会抛出异常使得程序不被执行

类加载器避免了出现某些怀有敌意的人编写自己的Java类而这些类方法中含有跳转到方法之外的指令导致虚拟机的崩溃和保密信息被获取的可能保证了程序的健壮性也不会出现替代原有Java API类的恶意代码被运行的情况并且类加载器防止了恶意代码去干涉善意的代码守护了被信任的API类库边界确保了代码可以进行的操作

安全管理器

安全管理器为Java虚拟

上一篇:如何防止被IE工具拦截导致无法弹出窗口

下一篇:JSP开发的安全编程实例详细解析