开发者学堂课程【高校精品课-上海交通大学-企业级应用体系架构:Security1 1】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/75/detail/15823
Security1 1(二)
内容介绍:
一、Java 的类加载器
二、 字节码的校验
三、安全管理器和权限
二、字节码的校验
类加载器要做的事情是检查类文件,首先变量在使用之前都定义过,都初始化过给的初值,方法调用与对象引用的类型相匹配等等,一些是 Java 编译器做过的检查,如果字节码里通不过 Java 编译器就说明存在问题,通过之后就说明没有问题。已经生成了 class 文件,通过Java编译器编译的,在 Java 虚拟机里面node字节还要再做一次检查,原因是字节码很容易被篡改,Java 虚拟机再做一个类的时候,可以使用 noverity 标签忽略掉其他的步骤,跳过指令,无论如何去执行 hello。还会有分享,字节码很容易被修改。
举例,这里定义了变量 m和 n,两个赋初值一个是1一个是2,计算他们的值,如果当时写的时候写错了,m赋完初值之后应该对n赋初值,但是没有写成n写成了m,底下的代码就会显示n是一个没有初始化的值,因此代码是不合法的,得到的int的值是随机的值。能够经过编译的代码,编译出来的字节码就会呈现出来,红色标记的3c表示n=2,随便拿一个二进制的编译器将3c改为3B,对应的代码就是上面错误的代码。也就是如果编译完了字节码,如果对字节码比较熟悉可以将字节码篡改,篡改之后的字节码可能会带有一定的危险,所以 Java虚拟机加载了字节码之后必须进行校验。如果不做可能会存在风险。
三、安全管理器和权限
字节码属于比较低成本的,初级的措施,下面讲在 Java 安全体系里面利用安全管理器和自定义权限来进行安全控制的机制。安全管理器是运行的时候想让 Java 虚拟机安装一个安全管理器去进行安全的监测。包括创建一个新的类加载器的时候就需要进行权限检测,看看代码是否有权限。比如要退出虚拟机的时候也要进行安全监测,看看是否有权限。之前没有遇到这种情况是因为在运行的时候并没有要求在安全管理器的管理之下执行,直接写的是 Java hello 去运行类。但是如果希望在运行程序的时候有安全管理器,就需要做安全检查执行的时候 Java hello 之间是要传参的,想要安装安全管理器在运行java 虚拟机的时候安全管理机就会起作用,在运行代码的时候起作用。能够起作用的代码比如退出虚拟机的代码就会判断当前系统是否有安全管理器,也就是在运行的时候有没有让他在安全管理器的管理下运行。如果不为空就说明系统在执行 hello 这个类的时候是安装了一个安装管理器的,需要让安全管理器去检查能不能退出 Java 虚拟机。如果没有就是为空的话要指定安全管理器直接就会退出。所以之前从来都没有安装安全管理器等于有一部分的代码是没有的,是不执行的从来没有起过作用,但是现在如果是要启动这一部分代码。
安全管理器会去读 policy 的文件,就是文件名是以 .policy 结尾的,就是一个策略,策略就是下图所画的,会去说某一些代码具有什么样的权限集合。比如有一个 permission 的 file 就是这个策略,策略中写会去对 tmp 的所有文件有文件操作的权限,可以对文件做读和写,policy 实际上是在指定针对哪些代码,具有什么样的权限。本节课的重点是 policy 怎样写,指定代码有三种方式,一种方式是按照位置,第二种方式比较复杂后面会讲,就是用户的认证,用户认证之后实际上会带一些特征叫做 princ:pol. 第二种是不管代码在哪里,只要执行,执行的线程上具有指定的 princ:pol 操作。第三种是不管是谁在执行,不管代码在哪里,只管代码是谁签名的,比如从谷歌上下载了插件,插件是谷歌签名过的东西,就认为它是安全可靠的就具有某一个权限集。有三种方式后面会去讨论三种方式分别是什么意思。
演化的原因是在最初的 Java 里面,如果是本地代码就具有全部权限。如果是远程代码,会在一个叫沙盒的运行环境中运行,很多权限都没有,非常抽象。比如从谷歌上面下载了一个插件,希望使用它,它的作用是在本地打开打印机去做一些操作,这时发现不允许,因为沙盒没有操作打印机的权限。
后来演变为远程的代码如果是授信的组织,比如谷歌签过名的代码就和本地代码一样,具有全部的权限,否则的话还是在沙盒里。这个方式的好处是要么什么都有,要么什么都没有,而且还区分本地和远程。