《Java白皮书1996自译》06:安全性

詹姆斯·高斯林

第六章 安全性

随着从软件和多媒体内容的电子分销到“数字现金”等产品和服务越来越多地使用互联网,安全要求越来越高。这里我们关心的安全领域是Java编译器和运行时系统如何限制应用程序程序员创建颠覆性代码。

Java语言编译器和运行时系统实现了针对可能不正确的代码的几层防御。环境从没有什么值得信任的假设开始,并相应地发展。接下来的几节将更详细地讨论Java安全模型。

6.1、内存分配和布局

Java编译器的主要防线之一是它的内存分配和引用模型。首先,内存布局决策不是由Java语言编译器做出的,因为它们是在C和c++中做出的。相反,内存布局被延迟到运行时,并且可能根据Java系统所执行的硬件和软件平台的特征而有所不同。

其次,在传统的C和c++中,Java没有包含其他内存单元地址的“指针”。Java编译的代码通过符号“句柄”引用内存,这些句柄在运行时由Java解释器解析为实际内存地址。Java程序员不能伪造指向内存的指针,因为内存分配和引用模型对程序员来说是完全不透明的,并且完全由底层运行时平台控制。

很晚才将结构绑定到内存意味着程序员不能通过查看类的声明来推断类的物理内存布局。通过删除C和c++内存布局和指针模型,Java语言消除了程序员在幕后伪造或以其他方式制造内存指针的能力。必须将这些特性看作是积极的好处,而不是对程序员的限制,因为它们最终会导致更可靠和安全的应用程序。

6.2、类加载器中的安全检查

当Java程序在执行时,它可能会反过来请求装载一个或一组特定的类,可能是从网络上装载的。在字节码验证器检查并确定传入代码是干净的之后,下一道防线是Java字节码装入器。运行Java字节码的执行线程所看到的环境可以被可视化为一组划分为不同名称空间的类。来自本地文件系统的类有一个名称空间,每个网络源有一个单独的名称空间。

当一个类从网络上导入时,它被放置到与其起源相关联的私有名称空间中。当一个类引用另一个类时,首先在本地系统的名称空间(内置类)中查找,然后在引用类的名称空间中查找。导入的类不可能“欺骗”内置类。内置类永远不会意外地引用导入的名称空间中的类——它们只能显式地引用这些类。类似地,从不同地方导入的类彼此分离。

6.3、字节码验证过程

那么“敌对编译器”的概念呢?尽管Java编译器将确保Java源代码不违反安全规则,当应用程序如HotJava浏览器进口来自任何地方的一个代码片段,它实际上并不知道如果代码片段遵循Java语言规则安全:产生的代码可能没有被认为是值得信赖的Java编译器。在这种情况下,您机器上的Java运行时系统如何信任传入的字节码流?答案很简单:Java运行时系统不相信传入的代码,而是对其进行字节码验证。

测试的范围从验证代码片段的格式是否正确,到通过一个简单的定理验证器传递每个代码片段,以确定它是否遵守规则:

●it doesn’t forge pointers,
●it doesn’t violate access restrictions,
● it accesses objects as what they are (for example, InputStream objects are always used as InputStreams and never as anything else).

  • 它不伪造指针;
  • 不违反访问限制;
  • 它按原样访问对象(例如,InputStream对象总是作为InputStreams使用,而从不作为其他任何对象)。

一种安全的语言,加上生成代码的运行时验证,建立了一组不能违反接口的基本保证。

6.3.1、字节码验证器

字节码验证器遍历字节码,构造类型状态信息,并验证所有字节码指令的参数类型。

字节码验证器

该图显示了从Java语言源代码到Java编译器、类装入器和字节码验证器,再到包含解释器和运行时系统的Java虚拟机的数据和控制流。重要的问题是,Java类装入器和字节码验证器对字节码流的主要来源不做任何假设——代码可能来自本地系统,也可能在地球的另一端运行。字节码验证器充当某种程度上的守门人:它确保传递给Java解释器的代码处于要执行的合适状态,并且可以在不破坏Java解释器的情况下运行。导入的代码在通过验证者的测试之前是不允许执行的。一旦验证完成,许多重要的属性是已知的:

●没有操作数堆栈溢位或溢位

●所有字节码指令的参数类型都是正确的

●对象字段访问是合法的——私有、公共或受保护的

虽然所有这些检查看起来都非常详细,但是当字节码验证器完成它的工作时,Java解释器就可以继续了,因为它知道代码将安全地运行。了解这些属性可以使Java解释器更快,因为它不需要检查任何东西。没有操作数类型检查和堆栈溢出检查。因此,解释器可以在不损害可靠性的情况下全速工作。

6.4、Java网络包中的安全性

Java的网络包提供了处理各种网络协议(FTP、HTTP、Telnet等)的接口。这是您在网络接口级别的前线防御。可以使用可配置的偏执狂级别设置网络包。你可以:

● 禁止所有网络访问

● 只允许对从其中导入代码的主机进行网络访问

● 如果代码来自外部,则只允许防火墙外的网络访问

● 允许所有网络访问

6.5、总结

Java在基于网络的环境中是安全的。Java语言的体系结构中立和可移植方面使其成为满足跨网络动态分发可扩展软件的挑战的理想开发语言。


好好学习,天天向上!继续下一章…


发布了36 篇原创文章 · 获赞 30 · 访问量 5921

猜你喜欢

转载自blog.csdn.net/goldentec/article/details/104779943