锁定老帖子 主题:JVM安全模型--基本沙箱
精华帖 (1) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (0)
|
||
---|---|---|
作者 | 正文 | |
发表时间:2010-06-01
最后修改:2010-06-01
本是整理到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 内部,类加载器是如何进行工作的:
类加载“双亲”委托机制对安全的作用: 在双亲委派模式下,启动类加载器可以抢在已安装扩展类加载器之前去加载类,而标准扩展类加载器可以抢在类路径类加载器之前去加载那个类,类路径类加载器又可以抢在网络类加载器之前去加载它。 这样,在使用双亲委派机制中,启动类加载器会在最可信的类库--- 核心 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级别安全机制后续文章中会整理出来……) 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
||
返回顶楼 | ||
发表时间:2010-06-02
貌似是对深入Java虚拟机这本书第一章的总结?
|
||
返回顶楼 | ||
发表时间:2010-06-02
EldonReturn 写道 貌似是对深入Java虚拟机这本书第一章的总结?
是的, 是阅读《深入Java虚拟机》中‘安全’一章的整理和总结,整理中也有加入自己的理解。 |
||
返回顶楼 | ||
浏览 5831 次