`

《深入Java虚拟机》学习笔记三:安全性(下)

    博客分类:
  • Java
阅读更多

5、Java虚拟机中内置的安全特性 
      Java虚拟机在执行字节码时还进行一些内置的安全机制的操作,这些机制大多数十Java类型安全的基础,这些机制如下: 
       1)类型安全的引用转换 
       2)结构化的内存访问 
       3)自动垃圾收集 
       4)数组边界检查 
       5)空引用检查 
       通过保证一个Java程序只能使用类型安全的、结构化的方法去访问内存,Java虚拟机使得Java程序更为健壮,可以阻挠那些黑客,是他们不能为了达到某些目的而破坏Java虚拟机的内在存储,也使得它们运行更为安全。 
       作为内存结构化访问的一个后备,Java虚拟机并未指明运行时数据空间在Java虚拟机内部是怎么分布的。运行时数据空间是指一些内存空间,Java虚拟机用这些空间来存储运行一个Java程序时所需要的数据:Java栈,一个存储字节码的方法区,以及一个垃圾收集堆(它用来存储由运行的程序创建的对象)。 
       访问一个class文件内部,将找不到任何内存地址。当Java虚拟机装载一个class文件时,由它决定将这些字节码以及其他从class文件中解析得到的数据放在内存的什么地方。当Java虚拟机启动一个线程的时,由它决定将为这个线程创建Java栈放到哪里。当它创建一个对象时,也是由它决定将这个对象放到内存中的什么地方。
       禁止对内存进行非结构化的访问,其实并不是Java虚拟机必须主动强制正在运行的程序这样做,这种禁止其实是字节码指令集本身的内在本质(因为在字节码中,没有办法表达非结构化的内存访问,即使你自己书写了字节码)。 
       但是,对于由支持Java虚拟机的类型安全机制所建立的安全屏障,还是有办法可以突破的,虽然字节码指令集没有向用户提供不安全的,非结构化的内存方法,但是可以绕过字节码,即调用本地方法。在调用本地方法时,Java安全沙箱完全不起作用。首先健壮性的保证对本地方法并不适用,虽然不能通过Java方法去破坏内存,但是可以通过本地方法可以达到这个目的。最重要的是,本地方法没有经过JavaAPI(绕过JavaAPI),所以当一个本地方法试图做一些具有破坏性的动作时,安全检查器并未被检查。这样,一旦某个线程进入一个本地方法,不管Java虚拟机内置了何种安全策略,只要这个线程运行这个本地方法,安全策略将不再对这个线程适用。因此,安全管理器中包含了一个方法,该方法用来确定一个程序是否能装载动态链接库,因为在调用本地方法时动态链接库是必须的。在调用本地方法前必须确认它是可信任的。 
       为了保证安全而内置的Java虚拟机的最后一个机制,就是异常的机构化错误处理,因为Java虚拟机支持异常,所以当一些违反安全的行为发生时,它会做一些结构化的处理,Java虚拟机将抛出一个异常或者一个错误,而不是崩溃,这个异常或者错误将导致这个错误线程的死亡,而不是使整个系统陷入瘫痪。(抛出一个错误总是导致抛出错误的线程死亡。)

6、安全管理器和JavaAPI 
       Java安全模型的前三个部分---类装载体系结构,class文件检查器以及Java中内置的安全特性---一起达到一个共同的目的:保持Java虚拟机的实例它正在运行的应用程序内部完整性,使得它们不被下载的恶意或有漏洞的代码侵犯。 
       Java安全模型的第四个部分是安全管理器,它主要用于保护虚拟机的外部资源不被虚拟机内运行的恶意或者有漏洞的代码侵犯,这个安全管理器是一个单独的对象,在运行Java的虚拟机中,它在访问控制—对于外部资源的访问控制—中起中枢作用。 
       安全管理器定义了沙箱的外部边界,是可以定制的,运行为程序建立自定义的安全策略。当JavaAPI进行任何可能不安全的操作时,它都会向安全管理器请求许可,从而强制执行自定义的安全策略。要向安全管理器请求许可,JavaAPI将调用安全管理器对象的“check”方法。因为在JavaAPI在进行一个可能不安全的操作前,总是检查安全管理器,所以JavaAPI不会在安全管理器建立的安全策略下执行被禁止的操作。 
       当一个JavaAPI即将进行一个潜在不安全的动作时,它将遵循以下两个步骤: 
       首先,JavaAPI的代码检查有没有安装安全管理器,如果没有安装,则跳过第二步直接执行这个潜在不安全操作。 
       否则,在第二步中,它将调用安全管理器中的合适的“check”方法,如果这个操作被禁止,那么这个”check”方法会抛出一个安全异常,这将导致该JavaAPI方法立即中止,这个潜在不安全的操作将不会被执行。 
       安全管理器负责两个方面的工作:说明一个安全策略以及执行这个安全策略。
7、代码签名和认证 
       Java安全模型很重要的一点是它支持认证,认证功能加强了用户的能力,使用户能通过实现一个沙箱来建立多种安全策略,这个沙箱可以依赖于为这个代码提供担保的对象来改变。 
       要对一段代码作担保或者签名,必须首先生成一个公钥/私钥对,用户保管那把私钥,而把公钥公开。一旦拥有了公钥/私钥对,就必须将要签名的class文件和其他文件放到一个JAR文件中,然后使用一个工具对整个JAR文件签名,这个签名工具将首先对JAR文件的内容进行单向散列计算,以产生一个散列,然后这个工具将用私钥对这个散列进行签名,并且将经过签名后的散列加到JAR文件的末尾,这个签名后的散列代表了你对这个JAR文件内容的数字签名。那些持有你的公钥的人将对JAR文件验证两件事:这个JAR文件确实是你签名的,并且你签名后这个JAR文件没有做过任何改动。 
       数字签名过程的第一步是一个单向散列计算,它输入大量数据但是产生少量数据,称为散列。 
       虽然认证技术并没有消除所有和放宽沙箱限制相关的风险,但是他可以减小这些风险。安全性是一种代码和安全之间的折中,安全风险越小,安全的代价就越大。

8、策略 
       Java安全体系结构的真正好处在于,它可以对代码授予不同层次的信任度来部分地访问系统。Java安全体系结构的主要目标之一就是使建立细粒度的访问拦截策略过程更为简单而且更少出错。

9、保护域 
       当类装载器将类型装入Java虚拟机时,它们将为每个类型指派一个保护域。

11、访问控制器 
       类java.security.AccessController提供了一个默认的安全策略执行机制,它使用栈检查来决定潜在不安全的操作是否被允许,这个访问控制器不能被实例化,它不是一个对象,而是集合在单个类中的多个静态方法。

 

分享到:
评论
4 楼 水上风荷 2010-01-26  
快乐柠檬 写道
快乐柠檬 写道
     


今天才发现。。。。。。。
3 楼 快乐柠檬 2010-01-21  
快乐柠檬 写道
     

2 楼 快乐柠檬 2010-01-21  
     
1 楼 快乐柠檬 2010-01-21  
     

相关推荐

Global site tag (gtag.js) - Google Analytics