深入Java虚拟机(3)——安全

版权声明:本文为博主原创文章,转载注明出处http://blog.csdn.net/u013142781

目录(?)[+]

因为网络允许多台计算机共享数据和分布式处理,所以它提供了一条入侵计算机系统的潜在途径,使得其他人可以窃取信息,改变或破坏信息,盗取计算机资源等等。为了解决由网络引起的安全问题,Java体系结构采用了一个扩展的内置安全模型,这个模型随着Java平台的主要版本不断发展:

1.0版本的基本沙箱 
1.1版本的代码签名和认证 
1.2版本的细粒度访问控制

Java安全模型侧重于保护终端用户免受从网络下载的、来自不可靠来源的、恶意程序(以及善意程序中的bug)的侵犯。为此,Java从JDK 1.0开始实现了一套沙箱环境(基本沙箱),沙箱对不可靠的活动进行了限制,程序可以在沙箱的安全边界内做任何事,但不能进行任何跨越这些边界的举动。

但由于最初的沙箱限制过于严格,善意(但不可靠)的代码常常无法进行有效工作。在版本1.1中,得到了改进,引入了基于代码签名和认证的信任模式。使得接收终端系统哦就能够可以确认一系列class文件(在一个jar文件中)已经由某一实体进行了数字签名(有效,可被信赖),并且在签名过后,这些class文件没有改动,这使得终端用户和系统管理员减少了对某些代码在沙箱中的限制,但这些代码必须已由可信任团体进行数字签名。

虽然版本1.1中发布的安全API包含了对认证的支持,但是实际上,除了提供完全信任和完全不信任策略(换句话说,代码要么完全被信任,要么我完全不被信任)以外,没有提供其他实际帮助。后面的1.2版本提供的API可以帮助建立细粒度的安全策略。

下面详细看看基本沙箱、代码签名和认证、细粒度访问控制是如何实现的。

基本沙箱

Java沙箱 安全建立在 Java 运行时环境的三个基本方面的基础上:ByteCode Verifier(字节码验证器)、Security Manager(安全管理器)以及 ClassLoader(类装入器)。

ByteCode Verifier:它确保所下载的代码被恰当地格式化,字节码(“Java 虚拟机”指令)没有违反这种语言或虚拟机的安全限制(无非法数据转换),没有执行指针寻址,内部堆栈不能溢出或下溢,以及字节码指令将拥有正确的类型参数。

Security Manager:它在尝试执行文件 I/O 和网络 I/O、创建新的ClassLoader、操作线程或线程组、启动底层平台(操作系统)上的进程、终止“Java 虚拟机”、将非 Java 库(本机代码)装入到 JVM、完成某种类型的窗口系统操作以及将某种类型的类装入到 JVM 中时发起运行时访问控制。

ClassLoader:Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。当运行一个程序的时候,JVM启动,运行bootstrapclassloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。

代码签名和认证

Java1.1的java.security包中引入的认证策略,认证能帮助用户通过实现一个沙箱来建立多种安全策略。认证可以使用户相信由某些团体担保的class文件具有高度的可信度,并且这些class文件没有在到达Java虚拟机之前的网络传输中被改变。这样,就可以简化沙箱对被认证代码的限制,针对由不同团体签名的代码建立不同的安全限制。

要对一段代码进行担保签名,首先要生成一个公钥/私钥对。用户要公开公钥,保管私钥。之后将要签名的class文件和其他文件放在一个JAR文件中,然后用诸如SDK中的jarsigner 工具对整个JAR文件签名。这个签名工具将首先通过单项散列计算,对JAR文件产生一个散列,然后用私钥对这个散列签名,并在JAR文件的末尾加上这个签名,从而完成你对这个JAR文件的数字签名。

数字签名的散列计算中大量输入的是组成JAR文件内容的字节流,产生的是不能包含所有输入信息的少量数据。这个计算是单向的:从大到小,从输入到散列。为了加强安全性,要用私钥进行加密。因为私钥加密是一个非常费时的过程,我们只对散列进行私钥的加密。公钥/私钥对具有如下特点:在仅给出公钥的情况下时,想要产生私钥是非常困难的,而且任何用私钥加密的代码都可以用配对的公钥才能解密。因为不同的输入可能产生相同的散列,而产生相同散列的概率主要依赖于散列的大小。在实际情况下,散列主要采用64位或128位,这样的长度要想从不同的输入中产生一个相同的散列的计算是不可行的。之后将这个加密后的散列值加到同一个JAR文件中,这个JAR文件还包含了你最初产生这个散列的文件。

接受者必须用公钥对签名散列进行解密,通过得到的结果和从JAR文件计算得到的散列是否相同,可以验证一个已经签名的JAR文件。如果得到的散列值和解密的散列值匹配,则表明了接受者收到的JAR文件确实被发送者所担保,并且传输过程中没有被修改,这个文件安全性是有保障的。这样,就可以将这个JAR文件放入安全级别不很严格的一般沙箱里,这个沙箱信任发送者的签名。

细粒度访问控制

版本1.2的安全体系结构的主要目标之一就是使建立(以签名代码为基础的)细粒度的访问控制策略的过程更为简单且更少出错。版本1.2的安全体系结构中,对应于整个Java应用程序的一个访问控制策略是由抽象类java.security.Policy的一个子类的单个实例所表示的。

安全策略是一个从描述运行代码的属性集合到这段代码所拥有的权限的映射。在版本1.2的安全体系结构中,描述运行代码的属性被总称为代码来源。一个代码来源是由一个java.security.CodeSource对象表示的,这个对象中包含了一个java.net.URL,它表示代码库和代表了签名者的零个或多个证书对象的数组。证书对象是抽象类java.security.cert.Certificate的子类的一个实例,一个Certificate对象抽象表示了从一个人到一个公钥的绑定,以及另一个为这个绑定作担保的人(以前提过的证书机构)。CodeSource对象包含了一个Certificate对象的数组,因为同一段代码可以被多个团体签名(担保)。这个签名通常是从JAR文件中获得的。

权限是用抽象类java.security.Permission的一个子类的实例表示的。一个Permission对象有三个属性:类型、名字和可选的操作。

在Policy对象中,每一个CodeSource是和一个或多个Permission对象相关联的。和一个CodeSource相关联的Permission对象被封装在java.security.PermissionCollection的一个子类实例中。

参考资料: 
《深入Java虚拟机 第二版》 
http://www.2cto.com/Article/201210/162438.html 
http://www.1k2k.net/ligongkeji/2012/0507/52776.html

时间: 2024-09-27 16:58:26

深入Java虚拟机(3)——安全的相关文章

java-《深入理解Java虚拟机》有关methodHandle的代码问题?

问题描述 <深入理解Java虚拟机>有关methodHandle的代码问题? 以下代码书上说是输出"i am grandfather",但远行实际输出为"i am father" class Test { class GrandFather { void thinking() { System.out.println("i am grandfather"); } } class Father extends GrandFather {

java虚拟机学习笔记

笔记 1.编译顺序:                 编译器                     虚拟机      虚拟机          java源文件*.java------->字节码*.class------>类装载器--->执行引擎 一个.class文件只能包含一个类或接口.因此.java文件中定义了多少类,编译时就会生成多少.class文件(内部类不算). 2.java程序可以选择两种方式访问底层系统,由程序员选择:(1).通过java程序调用javaapi调用本地方法,

虚拟机概论(六)——JAVA虚拟机模型

JAVA虚拟机模型 由于它的高度可移植性,JAVA已经成为Internet上的主要编程语言. "模拟机"的概念是计算机工业界经常使用的对虚拟机的解释之一.这种虚拟机概念和IBM版的虚拟机非常不同.在IBM的概念中,系统内存和资源被分割,成为当前机器的精确拷贝.而对于模拟机,系统并不被分割,而是有一台新的"机器"或者虚拟机加载到当前系统中,在不改变当前系统的前提下,向用户提供不同的功能.这种类型的虚拟机被证明是非常强大的,它允许软件开发人员在一台完全不同的机器上仿效另

java虚拟机学习笔记2

笔记 11.数组数组也是类的对象.具有相同类型和维数的数组属于同一个类(不管长度只看维数).数组的长度属于对象实例.多维数组也是一维数组.如二 维数组,即为一个一维数组,该一维数组的每个元素是一个数组的引用.数组和普通对象一样也存储在堆中.数组名为数组的引用,通过索引即数组标号来访问数组内容. 12.异常在java栈帧的帧数据区内保存有针对该方法的异常表的引用.异常表记载了该方法的字节码(*.class)受catch子句保护的范围(即try子句里的 字节码).当某个方法抛出异常时,虚拟机在对应的

Java基础:JVM(Java 虚拟机)的详细讲解

可能有很多学习Java的朋友还不知道Java的运行原理.Java虚拟机是怎么工作的,本文将为你详细讲解(JVM)Java 虚拟机. 在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口.编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行.在Java中,这种供虚拟机理解的代码叫做字节码(ByteCode),它不面向任何特定的处理器,只面向虚拟机.每一种平台的

Grails1.1和Groovy1.6的Java虚拟机的内存设置和调整

在这篇文章中,我希望回答下列问题: .Grails1.1和Groovy1.6的Java虚拟机的内存设置和调整隐藏在哪里,以及我们如何来改变它们? .最新的版本和旧的版本之间有什么不同? .以上这些设置和调整在windows和linux之间的不同需要我们掌握吗? Grails1.1和Grails1.0.2的Java虚拟机的内存设置 如果你运行grails命令,在linux/unix平台,它是执行"$GRAILS_HOME/bin/startGrails"命令:而在windows平台,是执

Java虚拟机

一. 什么是Java虚拟机 Java虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现.Java虚拟机有自己想象中的硬件,如处理器.堆栈.寄存器等,还具有相应的指令系统. 1.为什么要使用Java虚拟机? Java语言的一个非常重要的特点就是与平台的无关性.而使用Java虚拟机是实现这一特点的关键.一般的高级语言如果要在不同的平台上运行, 至少需要编译成不同的目标代码.而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译. Java虚拟机屏蔽了与具体平台相关的信息,

JVM(Java虚拟机)详解

可能有很多学习Java的朋友还不知道Java的运行原理.Java虚拟机是怎么工作的,本文将为你详细讲解(JVM)Java虚拟机. 在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口.编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行.在Java中,这种供虚拟机理解的代码叫做字节码(ByteCode),它不面向任何特定的处理器,只面向虚拟机.每一种平台的解

MIPS目标平台CLDC的Java虚拟机移植

1 Java虚拟机简介 Java ME(Java platform Micro Edition),以前称J2ME,是为机顶盒.移动电话和PDA等嵌入式消费电子设备提供的Java语言平台,它包括虚拟机和一系列标准化的Java API(Application Programming Interface).Java语言的平台无关性使其广泛应用于各行各业,而嵌入式领域Java ME技术的发展尤为迅猛.截至2008年底,JavaME技术已应用于全球26亿部移动手机.部署了60亿个Java Cards.4

Java虚拟机类装载的原理及实现

一.引言 Java虚拟机(JVM)的类装载就是指将包含在类文件中的字节码装载到JVM中, 并使其成为JVM一部分的过程.JVM的类动态装载技术能够在运行时刻动态地加载或者替换系统的某些功能模块, 而不影响系统其他功能模块的正常运行.本文将分析JVM中的类装载系统,探讨JVM中类装载的原理.实现以及应用. 二.Java虚拟机的类装载实现与应用 2.1 装载过程简介 所谓装载就是寻找一个类或是一个接口的二进制形式并用该二进制形式来构造代表这个类或是这个接口的class对象的过程,其中类或接口的名称是