标签:
Java虚拟机-安全沙箱
学习了一下Java的安全机制,以前学习C++的时候好像就从来没有考虑过太多安全方面的问题,一些代码方面的安全问题,诸如指针、内存什么的考虑过,但是整体的安全性基本无视,学习了这一章还是有蛮多收获。
组成沙箱的四个组件:
通过命名空间隔离类,使不同命名空间的类不会互相访问(显示指定了访问方式的例外),解决了类的访问范围问题,如下图:
类的加载(装载)顺序问题和防止恶意加载的方法,先看下图:
上图中的网络类装载器理解为用户自定义的装载器,启动类装载器是Java的顶级类装载器(顶级表示层次,不是性能、品味、奢侈等)和标准扩展类装载器理解为系统自带的类装载器。
例,当需要加载类A的时候,会先从父装载器开始寻找是否已经存在类A,如果没有,迭代寻找父装载器,直到启动类装载器返回结果,如果找到了,就由父装载器加载,如果都没有,则由自己加载。
类装载器加载类有一些保护规则,如下:
安全性开始进入到了类的内部了。Java虚拟机对class文件有4次检查:
二进制兼容问题,为什么要在动态连接时进行检查(上面第四条),一个原因是防止原有的class发生了变化,有专门的二进制兼容规则描述哪些情况是 可以兼容的。例如,在被调用的类中新添加方法是可以的,但是给老方法改名是不可以的。我个人的理解就是:以符号引用的方法进行动态连接,只要符号不变,就 OK,符号变了就不行。
重复一下,之前也有了解,多写一下,权当是背诵了。
下面是以前不太了解的:
每个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两个文件的权限。
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/flyingMonkey/p/4388549.html