本文共 2663 字,大约阅读时间需要 8 分钟。
参考:Java核心技术卷2 高级特性 第九章
Java技术提供了三种确保安全的机制:
类加载器,可以在将类加载到虚拟机中的时候检查类的完整性。
为了获得最大的安全性,无论是加载类的默认机制,还是自定义的类加载器,都需要与负责控制代码运行的安全管理器类协同工作。
Java编译器会为虚拟机转换源指令,虚拟机代码存储在以.class为扩展名的类文件,每个类文件都包含某个类或者接口的定义和实现代码。这些类文件必须由一个程序进行解释,该程序能够将虚拟机的指令集翻译成目标机器的机器语言。
虚拟机只加载程序执行时所需要的类文件。
虚拟机执行的步骤:
(1)虚拟机有一个用于加载类文件的极值,例如,从磁盘读取文件或者请求web上的文件,使用该机制来加载指定类文件中的内容。
(2)如果指定类拥有类型为另一个类的域,或者是拥有超类,那么这些类文件也会被加载(加载某各类所依赖的所有类的过程称为类的解析)。
(3)接着,虚拟机执行指定类中的main方法(它是静态的,无需创建类的实例)。
(4)如果main方法或者main调用的方法要用到更多的类,那么接下来就会加载这些类。
然而,类加载机制并非只使用单个的类加载器。每个Java程序至少拥有三个类加载器:引导类加载器、扩展类加载器、系统类加载器(有时也称为应用类加载器)。
引导类加载器负责加载系统类,通常从JAR文件rt.jar中进行加载。它是虚拟机不可分割的一部分,通常使用C语言来实现的。引导类加载器没有对应的ClassLoader对象。
扩展类加载器用于从jre/lib/ext目录加载“标准的扩展”。可以将JAR文件放入该目录,这样即使没有任何类路径,扩展类加载器也可以找到其中的各个类。
系统类加载器用于加载应用类。在由CLASSPATH环境变量或者-classpath命令行选项设置的类路径中的目录里或者是JAR/ZIP文件里查找这些类。
在Oracle的Java语言实现中,扩展类加载器和系统类加载器都是用Java来实现的。它们都是URLClassLoader类的实例。
类加载器有一种父子关系,除了引导类加载器外,每个类加载器都有一个父类加载器。根据规定,类加载器会为它的父类加载器一个机会,以便加载任何给定的类,并且只有在其父类加载器加载失败时,它才会加载给定类。
偶尔需要干涉和指定类加载器:
助手方法的类是由系统类加载器加载的,这是Class.forName所使用的类加载器。对于它来说,在插件JAR中的类是不可视的,这种现象称为类加载器倒置。要解决这个问题,助手方法需要使用恰当的类加载器,它可以要求类加载器作为其一个参数传递给它。或者,它可以要求将恰当的类加载器设置称为当前线程的上下文类加载器,这种策略在许多框架中都得到了应用。每个线程都有一个对类加载器的引用,称为上下文类加载器。主线程的上下文类加载器是系统类加载器。当新线程创建时,它的上下文类加载器会被设置称为创建该线程的上下文类加载器。因此,如果你不做任何特殊的操作,那么所有线程都会将它们的上下文类加载器设置为系统类加载器。通常,当调用不同的类加载器加载插件类的方法时,进行上下文类加载器的设置是一种好的思路。
在同一个细腻及中,可以有两个类,它们的类名和类加载器来确定的。这项技术在加载来自多处的代码时很有用。
编写自己的用于特殊目的的类加载器,这使得我们可以在向虚拟机传递字节码之前执行定制的检查。
当类加载器将新加载的Java平台类的字节码传递给虚拟机时,这些字节码首先要接受校验器的校验。校验器负责检查哪些指令无法执行的明显有破坏性的操作。除了系统类外,所有的类都要被校验。校验器执行的一些检查如下:
校验器总是在防范被故意篡改的文件,而不仅仅是检查编译器产生的类文件。
一旦某个类被加载到虚拟机中,并由检验器检查过之后,Java平台的第二种安全机制就会启动,这个机制就是安全管理器。
安全管理器就是一个负责控制具体操作是否允许执行的类。安全管理器负责检查的操作包括以下内容:
代码来源是由一个代码位置和一个证书集指定的,代码位置指定了代码的来源。证书的目的是要由某一方来保障代码没有被篡改过。权限是指由安全管理器负责检查的任何属性。
每个类都有一个保护域,它是一个用于封装类的代码来源和权限集合的对象。当SecurityManager类需要检查某个权限时,它要查看当前位于调用堆栈上的所有方法的类,然后要获取所有类的保护域,并且询问每个保护域,其权限集合是否允许执行当前正在被检查的操作。通过检查整个调用堆栈,安全机制就能够确保一个类决不会要求另一个类代表自己去执行某个敏感的操作。
策略管理器要读取相应的策略文件,这些文件包含了将代码来源映射为权限的指令。
可以将策略文件安装在标准位置上。默认情况下,有两个位置可以安装策略文件:
消息摘要是数据块的数字指纹,例如,所谓的SHA1可以将任何数据块,无论其数据多长,都压缩为160位(20字节)的序列。
消息摘要的两个基本属性:
Java编程语言已经实现了MD5、SHA-1、SHA-256、SHA-384和SHA-512。
转载地址:http://xgyai.baihongyu.com/