《深入解析Android 虚拟机》——2.3 JVM的安全性

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析DNS,个人版 1个月
访问控制,不限时长
简介: 除了平台无关性以外,Java还必须解决的另一个技术难题就是安全。因为网络运行多台计算机共享数据和分布式处理,所以它提供了一条侵入计算机系统的潜在途径,使得其他人可能窃取信息、改变或破坏信息、盗取计算资源等。因此,将计算机联入网络产生了很多安全问题。

本节书摘来自异步社区《深入解析Android 虚拟机》一书中的第2章,第2.3节,作者:钟世礼著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.3 JVM的安全性

除了平台无关性以外,Java还必须解决的另一个技术难题就是安全。因为网络运行多台计算机共享数据和分布式处理,所以它提供了一条侵入计算机系统的潜在途径,使得其他人可能窃取信息、改变或破坏信息、盗取计算资源等。因此,将计算机联入网络产生了很多安全问题。为了解决由网络引起的安全问题,Java体系结构采用了一个扩展的内置安全模型,这个模型随着Java平台的主要版本而不断发展。在本节的内容中,将简要讲解JVM安全性的基本知识,为读者步入本书后面知识的学习打下基础。

2.3.1 JVM的安全模型
Java安全模型侧主要用于保护终端用户免受从网络下载的、来自不可靠来源的、恶意程序的侵犯。为了达到这个目的,Java提供了一个用户可配置的“沙箱”,在沙箱中可以放置不可靠的Java程序。沙箱对不可靠程序的活动进行了限制,程序可以在沙箱的安全边界内做任何事,但是不能进行任何跨越这些边界的举动。例如,原来在版本1.0中的沙箱对很多不可靠Javaapplet的活动做了限制,主要包括:

对本地硬盘的读写操作;
进行任何网络连接,但不能连接到提供者applet的源主机;
创建新的进程;
装载新的动态连接库。
由于下载的代码不可能进行这些特定的操作,这使得Java安全模型可以保护终端用户避免受到有漏洞的代码的威胁。在沙箱内有严格的限制,其安全模型甚至规定了对不可靠代码能做什么、不能做什么,所以用户可以比较安全地运行不可靠代码。但是对于1.0系统的程序员和用户来说,这个最初的沙箱限制太过严格,善意的代码常常无法进行有效的工作。所以在后来的1.1版本中,对最初的沙箱模型进行了改进,引入了基于代码签名和认证的信任模式。签名和认证使得接收端系统可以确认一系列class文件已经由某一实体进行了数字签名(有效,可被信赖),并且在经过签名处理以后,class文件没有改动。这使得终端用户和系统管理员减少了对某些代码在沙箱中的限制,但这些代码必须已由可信任团体进行数字签名。

虽然1.1版本的安全API包含了对认证的支持,但是其实只是提供了完全信任和完全不信任策略。Java 1.2提供的API可以帮助建立细粒度的安全策略,这种策略是建立在数字签名代码的认证基础上的。Java安全模型的发展经历了1.0版本的基本沙箱,然后是1.1版本的代码签名和认证,最后是1.2版以后的细粒度访问控制。

2.3.2 沙箱模型的4种组件
在计算机系统中,个人电脑中运行一个软件的前提是必须信任它。普通用户只能通过小心地使用来自可信任来源的软件来达到安全性,并且定期扫描,检查病毒来确保安全性。一旦某个软件有权使用我们的系统,那么它将拥有对这台电脑的完全控制权。如果这个软件是恶意的,那么它就可以为所欲为。所以在传统的安全模式中,必须想办法防止恶意代码有权使用你的计算机。

沙箱安全模型使得工作变得容易,即使某个软件来自我们不能完全信任的地方,通过沙箱模型可以使我们接受来自任何来源的代码,而不是要求用户避免将来自不信任站点的代码下载到机器上。当运行来自不可靠来源的代码时,沙箱会限制它进行任何可能破坏系统的动作指令。并且在整个过程中,无需指出哪些代码可以信任,哪些代码不可以信任,也不必扫描查找病毒。沙箱本身限制了下载的任何病毒或其他恶意的,有漏洞的代码,使得它们不能对计算机进行破坏。

如果你还有疑问,在确信它能保护你之前,用户必需确认沙箱没有任何漏洞。为了保证沙箱没有漏洞,Java安全模型对其体系结构的各方面都进行了考虑。如果在Java体系结构中有任何没有考虑到安全的区域,恶意的程序员很可能会利用这些区域来绕开沙箱。因此,为了对沙箱有一个了解,必须先看一下Java体系结构的几个不同部分,并且理解它们是怎样一起工作的。

下面列出了组成Java沙箱的基本组件。

类加载体系结构。
class文件检验器。
内置于Java虚拟机(及语言)的安全特性。
安全管理器及Java API。
Java的上述安全模型的前3个部分——类加载体系结构、class文件检验器、Java虚拟机(及语言)的安全特性一起达到一个共同的目的:保持JVM的实例和它正在运行的应用程序的内部完整性,使得它们不被下载的恶意代码或有漏洞的代码侵犯。相反,这个安全模型的第四个组成部分是安全管理器,它主要用于保护虚拟机的外部资源不被虚拟机内运行的恶意或有漏洞的代码侵犯。这个安全管理器是一个单独的对象,在运行的Java虚拟机中,它在对于外部资源的访问控制起中枢作用。

2.3.3 分析Java的策略机制
沙箱安全模型的最大优点之一是可以是用户自定义的,通过从Java1.1版本就已经引入的代码签名和认证技术,使正在运行的应用程序可以对代码区分不同的信任度。通过自定义沙箱,被信任的代码可以比不可靠的代码获得更多的访问系统资源的权限。这就防止了不可靠代码访问系统,但是却允许被信任的代码访问系统并进行工作。Java安全体系结构的真正好处在于,它可以对代码授予不同层次的信任度来部分地访问系统。

Microsoft提供了ActiveX控件认证技术,它和Java的认证技术相类似,但是ActiveX控件并不在沙箱中运行。这样使用了ActiveX,一系列移动代码要么是被完全信任的,要么是完全不被信任的。如果一个ActiveX控件不被信任,则它将被拒绝执行。虽然这对于没有认证来说是一个很大的提高,但是如果一些恶意的或是有漏洞的代码得到了认证,这段危险的代码将拥有对系统的完全访问权。Java的安全体系结构的优点之一就是,代码可以被授予只对它需要的资源进行访问的有限权限。即使一些恶意的或者有漏洞的代码得到了认证,它也很少有机会进行破坏。例如,一段恶意的或者有漏洞的代码可能只能删除一个固定目录下的为它设置的文件,而不是在本地硬盘上的所有文件。

从1.2版本开始的安全体系结构的主要目标是建立(以签名代码为基础的)细粒度的访问控制策略,这样不但过程更为简单而且更少出错。为了将不同的系统访问权限授予不同的代码单元,Java的访问控制机制必须能确认应该给每个代码段授予什么样的权限。为了使这个过程变得容易,载入1.2版本或其他虚拟机的每一个代码段(每个class文件)将和一个代码来源关联。代码来源主要说明了代码从哪里来,如果它被某个人签名担保的话,是从谁那里来。在1.2版本以后的安全模型中,权限(系统访问权限)是授给代码来源的。因此如果代码段请求访问一个特定的系统资源,只有当这个访问权限是和那段代码的代码来源相关联时,Java虚拟机才会把对那个资源的访问权限授予这段代码。

在1.2版本的安全体系结构中,对应于整个Java应用程序的一个访问控制策略是由抽象类java.security.Policy的一个子类的单个实例所表示的。在任何时候,每一个应用程序实际上都只有一个Policy对象。获得许可的代码可以用一个新的Policy对象替换当前的Policy对象,这是通过调用Policy.setPolicy()并把一个新的Policy对象的引用传递给它来实现的。类装载器利用这个Policy对象来帮助它们决定,在把一段代码导入虚拟机时应该给它们什么样的权限。

安全策略是一个从描述运行代码的属性集合到这段代码所拥有的权限的映射。在1.2版本的安全体系结构中,描述运行代码的属性被总称为代码来源。一个代码来源是由一个java.security.CodeSource对象表示的,这个对象中包含了一个java.net.URL,它表示代码库和代表了签名者的零个或多个证书对象的数组。证书对象是抽象类java.security.Certificate的子类的一个实例,一个Certificate对象抽象表示了从一个人到一个公钥的绑定,以及另一个为这个绑定作担保的人(以前提过的证书机构)。CodeSource对象包含了一个Certificate对象的数组,因为同一段代码可以被多个团体签名(担保)。这个签名通常是从Jar文件中获得的。

从1.2版本开始,所有和具体安全管理器有关的工具和访问控制体系结构都只能对证书起作用,而不能对公钥起作用。如果附近没有证书机构,可以用私钥对公钥签名,生成一个自签名的证书。当使用keytool程序生成密钥时,总是会产生一个自签名的证书。例如在上一节的签名例子中,keytool不仅产生了“公钥/私钥”对,而且还为别名friend和stranger产生了自签名的证书。

权限是用抽象类java.security.Permission的一个子类的实例表示的。一个Permission对象有3个属性,分别是类型、名字和可选的操作。权限的类型是由Permisstion类的名字指定的,例如java.io.FilePermission、java.net.SocketPermission和java.awt.AWTPermission。权限的名字是封装在Permission对象内的。例如某个FilePermission的名字可能是“/my/finances.dat”,某个SocketPermission的名字可能是“applets.artima.com:2000”,某个AWTPermission的名字可能是“showWindowWithoutBannerWarning”。Permission对象的第3个属性是它的动作。并不是所有的权限都有动作。例如,FilePermission的动作是“read, write”,SocketPermission的动作是“accept, connect”。如果一个FilePermission的名字为“/my/finances.dat”,并且有动作“read, write”,那么它就表示对文件“/my/finance.dat”可以进行读写操作。名字和动作都是由字符串来表示的。

Java API有一个很大的权限层次结构,在里面表示了所有可能潜在危险的操作。可以根据自己的目的创建自己的Permission类来表示自定义的权限,例如可以创建一个Permission类来表示对属性数据库的特定记录的访问权限。定义自定义的Permission类也是一种扩展版本1.2的安全机制类满足自己需要的方法。如果创建了自己的Permission类,可以像使用Java API中的Permission类一样来使用它们。

在Policy对象中,每一个CodeSource是和一个或多个Permission对象相关联的。和一个CodeSource相关联的Permission对象被封装在java.security.PermissionCollection的一个子类实例中。类装载器可以调用Policy.getPolicy()来获得一个当前有效的Policy对象的引用。然后它们可以调用Policy对象的getPermission()方法,传入一个CodeSource,从而得到和那个CodeSource对应的Permission对象的PermissionCollection。然后类装载器可以使用这个从Policy对象中得到的PermissionCollection来帮助判断应该给导入的代码授予什么权限。

相关文章
|
20天前
|
Java Docker 索引
记录一次索引未建立、继而引发一系列的问题、包含索引创建失败、虚拟机中JVM虚拟机内存满的情况
这篇文章记录了作者在分布式微服务项目中遇到的一系列问题,起因是商品服务检索接口测试失败,原因是Elasticsearch索引未找到。文章详细描述了解决过程中遇到的几个关键问题:分词器的安装、Elasticsearch内存溢出的处理,以及最终成功创建`gulimall_product`索引的步骤。作者还分享了使用Postman测试接口的经历,并强调了问题解决过程中遇到的挑战和所花费的时间。
|
1月前
|
存储 安全 Java
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别;什么是程序计数器,堆,虚拟机栈,栈内存溢出,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
|
20天前
|
JSON Java Android开发
Android 开发者必备秘籍:轻松攻克 JSON 格式数据解析难题,让你的应用更出色!
【8月更文挑战第18天】在Android开发中,解析JSON数据至关重要。JSON以其简洁和易读成为首选的数据交换格式。开发者可通过多种途径解析JSON,如使用内置的`JSONObject`和`JSONArray`类直接操作数据,或借助Google提供的Gson库将JSON自动映射为Java对象。无论哪种方法,正确解析JSON都是实现高效应用的关键,能帮助开发者处理网络请求返回的数据,并将其展示给用户,从而提升应用的功能性和用户体验。
29 1
|
7天前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
51 0
|
7天前
|
开发者 云计算 数据库
从桌面跃升至云端的华丽转身:深入解析如何运用WinForms与Azure的强大组合,解锁传统应用向现代化分布式系统演变的秘密,实现性能与安全性的双重飞跃——你不可不知的开发新模式
【8月更文挑战第31天】在数字化转型浪潮中,传统桌面应用面临新挑战。本文探讨如何融合Windows Forms(WinForms)与Microsoft Azure,助力应用向云端转型。通过Azure的虚拟机、容器及无服务器计算,可轻松解决性能瓶颈,满足全球用户需求。文中还提供了连接Azure数据库的示例代码,并介绍了集成Azure Storage和Functions的方法。尽管存在安全性、网络延迟及成本等问题,但合理设计架构可有效应对,帮助开发者构建高效可靠的现代应用。
11 0
|
7天前
|
安全 开发者 数据安全/隐私保护
Xamarin 的安全性考虑与最佳实践:从数据加密到网络防护,全面解析构建安全移动应用的六大核心技术要点与实战代码示例
【8月更文挑战第31天】Xamarin 的安全性考虑与最佳实践对于构建安全可靠的跨平台移动应用至关重要。本文探讨了 Xamarin 开发中的关键安全因素,如数据加密、网络通信安全、权限管理等,并提供了 AES 加密算法的代码示例。
18 0
|
7天前
|
开发者 算法 虚拟化
惊爆!Uno Platform 调试与性能分析终极攻略,从工具运用到代码优化,带你攻克开发难题成就完美应用
【8月更文挑战第31天】在 Uno Platform 中,调试可通过 Visual Studio 设置断点和逐步执行代码实现,同时浏览器开发者工具有助于 Web 版本调试。性能分析则利用 Visual Studio 的性能分析器检查 CPU 和内存使用情况,还可通过记录时间戳进行简单分析。优化性能涉及代码逻辑优化、资源管理和用户界面简化,综合利用平台提供的工具和技术,确保应用高效稳定运行。
17 0
|
7天前
|
安全 数据安全/隐私保护 架构师
用Vaadin打造坚不可摧的企业级应用:安全性考虑全解析
【8月更文挑战第31天】韩林是某金融科技公司的架构师,负责构建安全的企业级应用。在众多Web框架中,他选择了简化UI设计并内置多项安全特性的Vaadin。韩林在其技术博客中分享了使用Vaadin时的安全考虑与实现方法,包括数据加密、SSL/TLS保护、结合Spring Security的用户认证、XSS防护、CSRF防御及事务性UI更新机制。他强调,虽然Vaadin提供了丰富的安全功能,但还需根据具体需求进行调整和增强。通过合理设计,可以构建高效且安全的企业级Web应用。
17 0
|
16天前
|
测试技术 API Android开发
Android经典实战之简化 Android 相机开发:CameraX 库的全面解析
CameraX是Android Jetpack的一个组件,旨在简化相机应用开发,提供了易于使用的API并支持从Android 5.0(API级别21)起的设备。其主要特性包括广泛的设备兼容性、简洁的API、生命周期感知、简化实现及方便的集成与测试。通过简单的几个步骤即可实现如拍照、视频录制等功能。此外,还提供了最佳实践指导以确保应用的稳定性和性能。
29 0
|
2月前
|
域名解析 安全 物联网
阿里云EMAS HTTPDNS 扩展全球服务节点:提升解析安全性与网络覆盖
阿里云EMAS HTTPDNS新增国内西南、华南及国际欧洲、美东服务节点,提升了全球覆盖能力与性能。作为高效域名解析服务,EMAS HTTPDNS针对互联网、汽车、物流、IOT等行业提供支持,解决了传统解析易遭劫持等问题。新增节点优化了就近调度功能,显著缩短响应时间并增强了服务稳定性和连续性,尤其为中国企业的海外业务提供了强有力的支持。此次扩展展现了阿里云对服务质量的持续追求和全球市场布局的战略思考。

推荐镜像

更多
下一篇
DDNS