预计阅读本页时间:-
9.8.7 Java安全性
人们设计了Java编程语言和相关的运行时系统,是为了一次编写并编译后就能够在Interent上以二进制代码的形式运行在所有支持Java的机器上。从一开始设计Java语言开始,安全性就成为其重要的一部分。在这一小节,我们来看看它的工作原理。
Java是一种在类型上安全的编程语言,也就是说编译器会拒绝任何与自身类型不一致的变量使用。而C语言正好相反,请看下面的代码:
naughty_func()
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
{
char *p;
p=rand();
*p=0;
}
代码把产生的随机数放在指针p中。然后把0字节存储在p所包含的地址中,覆盖了地址里原先的任何代码和数据。而在Java中,混合使用类型的语句是被语法所禁止的。而且,Java没有指针变量、类型转换、用户控制的存储单元分配(如malloc和free),并且所有的数组引用都要在运行时进行校验。
Java程序被编译成一种叫做JVM(Java Virtual Machine)字节码的中间形态二进制代码。JVM有大约100个指令,大多数指令是把不同类型的对象压入栈、弹出栈或是用算术合并栈里的对象。这些JVM程序通常是解释执行程序,虽然在某些情况下它们可以被编译成机器语言以便执行得更快。在Java模式中,通过Internet发送到远程计算机上运行的Applet是JVM程序。
当Applet到达远程计算机时,首先由JVM字节码校验器查看Applet是否符合规则。正确编译的Applet会自动符合规则,但无法阻止一个恶意的用户用汇编语言写JVM格式的Applet。校验的规则包括:
1)Applet是否伪造了指针?
2)是否违背了私有类成员的访问限制?
3)是否试图把某种类型的变量用作其他类型?
4)是否产生栈上溢或下溢?
5)是否非法地将变量从一种类型转换为另一种类型?
如果Applet通过了所有的测试,它就能被安全地执行并且不用担心它会访问非自己所有内存空间。
但是Applet也可以通过调用Java方法(过程)来执行系统调用。Java处理这种调用的方法也在不断在进步。在最初的Java版本JDK(Java Development Kit)1.0里,Applet被分为两类:可信的与不可信的。从本地磁盘取出的Applet是可信的并被允许执行任何所需要的系统调用。相反,从Internet获取的Applet是不可信的。它们被限制在沙盒里运行,如图9-38所示,实际上并不能做什么事。
在从这一模式中取得了些经验后,Sun公司认为对Applet的限制太大了。在JDK 1.1版本里,引入了版本标注。当Applet从Internet传递过来后,系统首先查看Applet是否有用户信任的个人或组织标注(通过用户所信任的标注者列表来定义)。如果是,Applet就被允许做任何操作,否则就必须在沙盒里运行并且受到很强的限制。
在获取了一些经验后,代码标注也不那么令人满意了,所以安全模式又有了变化。JDK 1.2版本提供了一套可配置的严密的安全策略,针对包含本地和异地所有的Applet。安全模式非常复杂导致需要整整一本书来描述(Gong,1999),我们仅仅归纳出一些精华的部分。
每一个Applet具有两个特性:来源于何处以及谁签署了它。来源于何处是指URL;谁签署了它是指签名所用的私钥。每个用户都能创建包含规则列表的安全策略。规则列出了URL、签署者、对象以及如果Applet的URL和签署者匹配规则时可在对象上执行的动作。从概念上来说,上述信息如图9-39所示,虽然真正的格式有所不同并且与Java的类等级有关。

其中的一种允许的动作是访问文件。该动作可以指定某一特定的文件或目录,给定目录下的所有文件,或给定目录下所有的文件和子目录的递归集合。图9-21的三行包含了3种情况。在第一行里,用户Susan建立了她的许可文件,这样来自她的税务预备用计算机,www.taxprep.com,并由该公司签名的Applet可以访问位于1040.xls文件里的她的税务数据。这是惟一可读的文件,并且任何其他的Applet都不能读。而且,来自于所有资源的所有Applet,无论是否签名,都可以读写/usr/tmp中的文件。
而且,Susan也信任Microsoft,让来自于该公司站点并签名过的Applet读、写或删除Office目录下的所有文件。例如,修复bug并安装新的软件版本。为了校验签名,Susan要么在她的磁盘里存放公钥,要么动态地获取公钥,例如,在持有她所信任的公司的公钥以后,使用该公司的签名证书格式。
文件不是仅仅要保护的资源。网络访问也可以被保护。被保护的对象是特定计算机的特定端口。每一台计算机由一个IP地址或DNS名确定;计算机上的端口由一排数字确定。可能的动作包括要求连接远程计算机以及接受来自远程计算机的连接。通过这种方法,Applet可以获得访问网络的权限,但仅局限于与许可列表中明示的计算机进行交谈。Applet可以动态地装入所需的附加代码(类),但用户提供的类装载器可以精确地控制由哪台计算机产生这样的类。当然还有其他大量的安全特性。