`
gogole_09
  • 浏览: 201648 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JVM安全模型--基本沙箱

阅读更多

 

  本是整理到word文档中,发到je上格式好像变得怪怪的,附件附上原来的word版本,需要的朋友可以下载回去看看.


安全模型简介

安全模型使Java 成为网络环境的技术,因为它们建立了对网络移动代码安全执行的必要的可信机制。

Java安全模型侧重于保护终端用户免受从网络下载的、来至于不可靠来源的、恶意程序的侵犯。而“沙箱”机制成为了这一目的的支持机制,在“沙箱”中存放不可信的 Java 程序。“沙箱”对不可靠的程序的活动进行了限制,程序可以在“沙箱”的安全边界内做任何事,但是不能进行任何跨越这些边界的举动。

比如说, 在版本 1.0 中的沙箱对于很多不可靠的 applet 进行了如下限制:

a.  对本地硬盘的读写

b.  进行任何网络连接,但是不能连接到提供这个applet 的源主机

c.  创建新的进行

d.  装载新的动态链接库

 

但是,基于版本1.0 的沙箱模型过于严格,有些善意(但是不可靠)的代码常常无法进行有效的工作,所以,在版本 1.1 ,“沙箱”模型得到了改进,引入了基于代码签名和认证的信任模型。

基本沙箱

Java沙箱的基本组成组件有:

1. 类加载器结构

2. Class文件检验器

3. 内置于Java 虚拟机的安全特性

4. 安全管理器及Java API

 

其中最重要的特点是: 组件当中的 类加载器 以及 安全管理器 是可以由 用户定制的.

 

在版本1.0 1.1 中的安全管理器负责处理访问控制 ( 包括安全策略规范和运行时安全策略 ) 的实施 所以,要在 1.0 1.1 中建立定制的策略,必须编写自己定制安全管理器。

在版本1.2 中,可以利用 Java2  平台提供的安全管理器,允许用户在一个和程序分离的 Ascii 策略文件中说明安全策略。在运行时,这个预先指定好的安全管理器获得一个类(访问控制器)的帮助,来执行这个策略文件中的安全策略。

 

下面我们来看沙箱结构中的类加载器结构:

类加载器

类加载器作为Java 沙箱中的第一道防线,毕竟是由于类加载器将代码装入到 JVM 中的。

类加载器在以下三个方面对Java 的沙箱起着作用:

Ø  它防止恶意代码去干涉善意的代码

Ø  它守护了被信任的类库的边界

Ø  它将代码归入某类(成为保护域),该类确定了代码可以进行哪些操作

 

   类加载器体系结构可以防止恶意的代码去干涉善意的代码,这是通过由不同的类加载器装入的类提供不同的命名空间来实现的。

 

什么是命名空间?

举例来说明吧,比如说,有一个类名字为A, 一旦 JVM 将一个 A 装入到特定的命名空间,它就不能再加载名为 A 的其他类到相同的命名空间了。

JVM 中,同一个命名空间的类可以直接进行交互,而不同的命名空间的类甚至不能察觉到彼此的存在,除非显式的提供了允许它们进行交互的机制 ( 通过包全名 )

 

对于用户自定义的类加载器来说,它常常依赖于其他的类加载器,比如JVM 的启动时的类加载器,来帮助自己加载一些类。

在版本1.2 之前,非启动类加载器必须显式的寻求于其他类加载器,类加载器可以请求另外一个用户自定义的类加载器来加载一个类,通过调用被请求的类加载器的 loadClass() 方法来实现的。除此以外,类加载可以通过调用 findSystemClass() 来请求启动类加载器来加载类,这是类 ClassLoader 中的一个静态方法。

在版本1.2 以后,类加载器请求另外一个类加载器来加载类型的过程被形式化,称为“双亲委托制”,从 1.2 开始,除启动类加载器以外的每一个类加载器,都有一个“双亲”类加载器,在某个特定的类加载器试图以常用方式加载类型以前,它会先默认地将这个任务“委托”给他 / 它的双亲 , 来请求它的双亲来加载这个类型 . 当然,这个双亲也依次请求它自己的双亲来加载这个类,这个过程一直向上继续,直到达到启动类加载器,通常启动类加载器 是委托链的最后一个类加载器。

1.2 以后,由用户自定义类加载来负责其他类型的加载,比如说,应用程序运行的 class  文件,在类路径中加载的 class 文件等 .

 

下面我们来看看,在JVM 内部,类加载器是如何进行工作的:

 

场景:加载一个名称为JVMTest 的类 .

 流程:

JVM启动时,实例化了 2 个用户自定义的类加载,一个“已安装扩展”的类加载器,一个是“类路径”类加载器

运行Java 应用程序,类加载发出一个加载 JVMTest 类的请求,类加载器询问它的双亲 ---- 类路径加载器来查找并加载这个类,这个类路径类加载依次向自己的双亲发出同样的请求,它的双亲既为已安装扩展的类加载器。这个类加载器也是首先请求它自己的双亲 ------- 启动类加载器。 

现在,假设JVMTest 不是 JAVA API 的一部分。也不是已安装扩展的一部分,也不在类路径上,所有这些类加载器都返回而不会提供一个名为 JVMTest 的已加载的类。当类加载回答说,它和所有的双亲都不能加载这个类时,你的类加载可能将试图用它自己的特定方式来加载 JVMTest 类,这样 JVMTest 就可以在应用程序以后的执行过程中发挥出作用。

接着来看后面的场景, 现在JVMTest 类已经被加载了,并可以使用了,假设以后的某一个时刻 JVMTest 类的一个方法被调用,并且这个方法引用了 Java api java.util.HashMap 类,因为这个引用是首次被运行的程序使用,所以虚拟机会请求你的类加载器(加载 JVMTest 的)来装载 java.util.HashMap 。 就像以前一样,你的类加载首先将请求传递给双亲,然后一路向上委派给启动类加载器,但是这一次,启动类加载可以将 java.util.HashMap 类返回给你的类加载器,因为启动类加载器可以找到这个类,所以从这一刻开始,不管何时 JVMTest 引用名为 java.util.HashMap 的类, JVM 就可以直接使用这个 java.util.HashMap 类了。

 

 

类加载“双亲”委托机制对安全的作用:

在双亲委派模式下,启动类加载器可以抢在已安装扩展类加载器之前去加载类,而标准扩展类加载器可以抢在类路径类加载器之前去加载那个类,类路径类加载器又可以抢在网络类加载器之前去加载它。 这样,在使用双亲委派机制中,启动类加载器会在最可信的类库--- 核心 Java API 中首先检查每个被加载的类型,然后依次到标准扩展、类路径上的本地类文件中检查,所以,

如果网络类加载器发出尝试通过下载加载一个和Java API 中某个类型同名的类型,例如:

java.lang.Integer,则这样的加载不会成功。因为在 Java API 中, java.lang.Integer 存在,它将被启动类加载器加载进 JVM ,而网络类加载器则没机会再次加载同名的 java.lang.Integer ,它只能使用双亲返回的类,所以这样就有效的防止了不可靠代码的不安全运行。

 

 

Class文件检验器

与类加载器一起,class 文件检验器保证加载的 class 文件内容有正确的内部结构,并且这些 class 文件相互协调一致。其实现的安全目标之一就是保证程序的健壮性 .

检验器主要分为四趟来检查这个class 文件的内部结构 .

1. 在类被加载时进行,检查这个class 文件,保证它被安全编译

2.  

3. 与第2 趟一起,在连接过程中进行, class 验证器确认类型数据遵循 Java 编程语言的语义 .

4. 在进行动态连接过程中解析符号引用时进行的,class 验证器确认被引用的类、字段以及方法确实存在。

 

简单介绍一下,每一个流程所做的一些事情:

第一趟,class 文件的结构检查

Class文件内部,检查是否以魔数开头 (0XCAFABABE) ,再检查 class 文件的主次版本号,然后检验是否数据不完整,内容是否有删节等……

 

第二趟,类型数据的语义检查

主要检验class 每个组成部分,确认它们是否是其所属类型的实例,它们的结构是否正确。例如,检验器强制规定除 Object 类以外的所有类,都必须有一个父类,另外还要检查 final 类没有被子类化,而且 final  方法没有被覆盖 . 也就是说, class 文件检验器在运行时检查了一些 Java 语言应该在编译时遵守的强制规则 .

 

第三趟,字节码验证

JVM对字节流进行数据流分析,这些字节流代表的是类的一些方法。这里引入两个特别的概念,字节码和栈帧

什么叫字节码?

由被成为操作码的单字节指令组成的序列,每个操作码后都跟着一个或多个操作数 可以通过 javap  命令来查看字节码

什么叫栈帧?

栈帧其实就是一个内存片段,其中存储着局部变量和计算的中间结果.

 

第四趟,符号引用的验证

JVM将会跟踪那些引用 ---- 从被验证的 class 文件到被引用的 class 文件,以确保这个引用是正确的。

大多数JVM 的实现采用延迟加载类的策略、直到类真正地被程序使用时才加载。即使一个实现确实预先加载这些类,这是为了加快加载过程的速度,那它还是会表现为延迟加载。

 

 

Java虚拟机中内置的安全特性

JVM中内置的安全特性有 :

Ø  类型安全的引用转换

Ø  结构化的内存访问(无指针算法)

Ø  自动垃圾收集(不必要显式的释放被分配的内存)

Ø  数组边界检查

Ø  空引用检查

 

(PS,Java安全管理器以及JavaAPI级别安全机制后续文章中会整理出来……)

分享到:
评论
2 楼 gogole_09 2010-06-02  
EldonReturn 写道
貌似是对深入Java虚拟机这本书第一章的总结?

是的, 是阅读《深入Java虚拟机》中‘安全’一章的整理和总结,整理中也有加入自己的理解。
1 楼 EldonReturn 2010-06-02  
貌似是对深入Java虚拟机这本书第一章的总结?

相关推荐

Global site tag (gtag.js) - Google Analytics