学习了一下Java的安全机制,以前学习C++的时候好像就从来没有考虑过太多安全方面的问题,一些代码方面的安全问题,诸如指针、内存什么的考虑过,但是整体的安全性基本无视,学习了这一章还是有蛮多收获。
沙箱
组成沙箱的四个组件:
-
类装载器
-
class文件检验器
-
Java虚拟机内置的安全特性
-
安全管理器
类装载器
通过命名空间隔离类,使不同命名空间的类不会互相访问(显示指定了访问方式的例外),解决了类的访问范围问题,如下图:
类的加载(装载)顺序问题和防止恶意加载的方法,先看下图:
上图中的网络类装载器理解为用户自定义的装载器,启动类装载器是Java的顶级类装载器(顶级表示层次,不是性能、品味、奢侈等)和标准扩展类装载器理解为系统自带的类装载器。
例,当需要加载类A的时候,会先从父装载器开始寻找是否已经存在类A,如果没有,迭代寻找父装载器,直到启动类装载器返回结果,如果找到了,就由父装载器加载,如果都没有,则由自己加载。
类装载器加载类有一些保护规则,如下:
- 使用父装载器优先加载类的方式,能够防止系统类被替换。例,从网络上加载java.land.Integer将会被拒绝,因为由启动类装载器加载的Java API中已经存在,所以原Integer不会被替换。
- 只有由同一个类装载器加载的且同一个包内的类才可以互相访问。例,一个自己写的病毒类java.lang.Virus,由于系统中不存在该类,所以上面的约束1无效,由网络类装载器加载成功,而且与java.lang.*类在同一个包,但是由于类装载器不相同,所以Virus也无法访问java.lang.*。
- 增加黑名单。类装载器可以指定禁止加载的类列表,如果发现企图加载,则立即抛出异常。
class文件检验器
安全性开始进入到了类的内部了。Java虚拟机对class文件有4次检查:
- class文件的结构检查。在类被加载时进行。文件格式检查,检查包头、版本、文件长度等。
- 类型数据的语义检查。在连接过程中进行。class文件检验器在运行时检查了一些Java语言在编译时应该遵守的强制规则。
- 字节码验证。在连接过程中进行。我的理解就是检查方法,对方法(操作码、操作数)进行检查,确保能够正确访问。由于“停机问题”的缘故,检查的规则是一个特定的规则集合,而不是所有可能的情况。
- 符号引用的验证。这个是在动态连接的过程中,对外部调用的检查。例,NoClassDefFoundError并不是在预加载过程弹出的,而是直到这个不存在的类首次被程序使用的时候才弹出。顺便提一下,动态连接时,查找被引用的类(如果需要就加载该类),把符号引用转换为直接引用(指针、偏移量)。
二进制兼容问题,为什么要在动态连接时进行检查(上面第四条),一个原因是防止原有的class发生了变化,有专门的二进制兼容规则描述哪些情况是可以兼容的。例如,在被调用的类中新添加方法是可以的,但是给老方法改名是不可以的。我个人的理解就是:以符号引用的方法进行动态连接,只要符号不变,就OK,符号变了就不行。
Java虚拟机内置的安全特性
重复一下,之前也有了解,多写一下,权当是背诵了。
- 类型安全的引用转换(强制显示类型转换)
- 结构化内存访问(无指针)
- 自动垃圾回收
- 数组边界检查
- 空引用检查
下面是以前不太了解的:
- 不指明运行时数据空间分布。Java栈(每个线程一个)、方法区、垃圾收集堆的数据都不预先指明内存地址,只在运行时由Java虚拟机分配。
- 本地方法不受Java虚拟机安全性的限制。只要开始运行本地方法,就跳出了Java虚拟机的沙箱了。比较安全的做法,是不要直接调用本地方法,通过Java API进行调用,这样可以利用Java API本身的安全性来控制。
- 线程死亡不影响其它线程。
安全管理器
每个Java应用程序只有一个Policy对象,通过java.security.Policy.setPolicy()可以使用新的Policy对象替换当前的Policy对象,类装载器利用这个Policy对象来帮助它决定在把一段代码导入虚拟机时给它们赋予什么样的权限,另外,类装载器也可以自行添加其它的权限或者无视Policy的权限。
关于代码源(CodeSource)、签名和保护域,只用下图来稍作解释:
上图示例是Friend类经过编译后为Friend.class和Friend$1.class两个文件,打包为friend.jar,在方法区中为Friend和Friend$1(这个我现在还不太明白)。需要限制它对question.txt和answer.txt两个文件的权限。
- CodeSource由唯一的代码URL和签名[0…N]组成,上图中是文件系统中的friend.jar和friend签名组成,签名可以没有。
- 文件的权限是权限的一种,一个权限(Permission)表示为类型、属性和动作。如FilePermission、“question.txt”、“read”表示对question.txt的文件权限为读。
- 多个权限组成PermissionCollection,图中表示为Permissions。
- 保护域(ProtectionDomain)就是将CodeSource与多个权限关联起来。
Policy对象有一个getPermission的方法,通过传入一个CodeSource,可以获得其对应的Permissions。
访问控制器
java.security.AccessController提供了一个默认的安全策略执行机制,使用栈检查方式来决定操作是否被允许。这个类不能被实例化,它只包含多个静态方法。
核心函数是void checkPermission(Permission),如果允许,则简单返回,如果不允许,则抛出AccessControllerException或其子类。
老版本采用的是直接的函数调用,在Java1.2版本中将老版本的函数简单化为:实例化为对应的Permission,调用checkPermission函数。
Permission、PermissionCollection和ProtectionDomain都有一个implies(Permission)方法,Permission中的implies的作用是看自身的权限是否包含了参数中Permission的权限,PermissionCollection和ProtectionDomain的implies的作用是看自身集合的权限是否包了参数中Permission的权限。
权限的栈检查,检查到没有权限就抛出错误,否则正常返回。
doPrivilege()方法将终止栈检查来获得检查的方便性。检查执行到doPrivilege的下一步停止。如果doPrivilege的权限小于自身的权限,则自身的权限会被降低到doPrivilege中提供的权限。
其它
Java不能解决的是内存一直增长,线程太多可能会很慢,没有用户和权限的映射(如Unix,不知道现在有没有)。
安全还有其它方面的问题,比如物理上的,有人把东西偷了,你的员工是间谍等等。
本文转自:http://www.cnblogs.com/Y/archive/2011/03/24/JavaVM_Learning_Chapter3_Security.html
非常感谢作者分享
相关推荐
3.5 java虚拟机中内置的安全特性 3.6 安全管理器和java api 3.7 代码签名和认证 3.8 一个代码签名示例 3.9 策略 3.10 保护域 3.11 访问控制器 3.11.1 implies()方法 3.11.2 栈检查示例 3.11.3...
6. **安全模型**:讨论了Java虚拟机的安全模型,包括沙箱机制(sandboxing)、访问控制等方面的内容。 7. **性能考量**:虽然虚拟机规范本身并不直接涉及性能优化,但在实际应用中,理解这些基础知识对于提高程序效率...
Java虚拟机通过多种方式保障程序的安全性: 1. **类型安全**:JVM确保所有类型的使用都是正确的,例如防止数组越界或非法类型转换等问题。 2. **内存保护**:通过内存管理机制,JVM可以防止程序访问非法内存区域,...
Java虚拟机(JVM)是Java程序运行的核心组件,它为Java应用程序提供了运行环境。"jre-1_5_0_08-windows-i586-p-s"这个标题表明我们正在讨论的是Java运行时环境(JRE)的一个特定版本,具体来说是1.5.0_08,这是一个...
Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java程序提供了运行环境。Java虚拟机1.6版本,也被称为JDK 1.6,是Sun Microsystems(后被Oracle收购)在2009年发布的一个重要版本。这个版本以安全性和稳定性...
- **安全性**:通过沙箱模型等技术确保代码安全执行。 ### JVM的架构 Java虚拟机的架构通常包括以下几个主要部分: 1. **类加载器子系统**:负责加载和验证Java类,确保它们符合JVM规范。 2. **运行时数据区**:...
- **安全性**:规范定义了一系列安全机制,如沙箱模型、类型检查等,这些机制保证了Java程序的安全运行。 - **可移植性**:规范提供了足够的灵活性,使得Java虚拟机能够在多种不同的硬件和操作系统环境下高效运行。 ...
《深入Java虚拟机第二版》是探讨Java虚拟机(JVM)内部工作原理的经典之作,作者Bill Venners通过本书深入浅出地解析了Java虚拟机的体系结构和内部机制,为Java开发者提供了编写高效程序的基础理论支持。 Java...
综上所述,Java沙箱安全模型通过类装载器、类文件校验器以及Java虚拟机自身的安全特性,构建了一个多层防护的安全体系。这些机制相互配合,共同确保了Java应用程序的安全性和稳定性。通过对沙箱模型的理解,开发者...