Java安全的基本功能
l 可配置的安全策略可以防止Java程序非法读取文件, 或非法建立与其他主机的网络连接, 或在未经允许的情况下访问打印机等等. 此策略建立在Java的存取控制机制上, 相应的存取控制器则依赖于Java的类装载器, 安全管理器和语言保护等安全机制.
l 要判定程序所读取的数据是否被修改过, 可以简单地利用生成消息摘要的方式来实现, 但这种方式安全性并不很高.
l 如果对完事性要求很高, 那么可以生成数字签名来检测程序所读取的数据是否被修改过.
l 密钥管理系统可以管理数字签名时用到的密钥.
l 为了支持以上技术, 需要一个扩展的基础设施.
Java加密扩展包(JCE)
JCE的作用是提供以下的安全操作:
l 加密(密码)
l 安全密钥交换
l 安全消息摘要
l 提供另一种密钥管理系统
JCE包括一组文档以及4 个jar文件
1. $JAVA_HOME\jre\lib\security\US_export_policy.jar
2. $JAVA_HOME\jre\lib\jce.jar
3. $JAVA_HOME\jre\lib\local_policy.jar
4. $JAVA_HOME\jre\lib\ext\sunjce_provider.jar
Java安全套接字扩展包(JSSE)
JSSE提供了SSL(Secure Sockets Layer, 安全套接字层)的加密功能. 如果需要与SSL服务器或SSL客户通信, 可以使用此扩展包中的API. 如果服务器和客户的实现中都需要增加加密功能, 则不仅可以使用JSSE, 也可以使用JCE的密码功能.
JSSE包括文档及3个jar文件:
1. $JAVA_HOME/jre/lib/jsse.jar(java后期版本已经将jcert.jar和jnet.jar整合到jsse.jar中)
java鉴别与授权服务(JAAS)
JAAS可以在Java平台上提供用户身份鉴别. 在Java平台上, 其功能是独一无二的. Java安全设计的所有核心功能都是为了保护终端用户不受程序开发者的影响, 由于终端用户为了使用开发者提供的程序,不得不满足其对本地资源的存取需求, 这就要示必须保证用户不受到程序的影响. 另一方面, JAAS允许开发者根据用户提供的鉴别信任状(credential)准许(或拒绝)用户对程序的访问.
JAAS主要由认证和授权两大部分构成. 认证就是简单地对一个实体的身份进行判断;而授权是向实体授予对数据资源和信息访问权限的决策过程. 从1.4版本开始, JDK已经开始集成JAAS.
JAAS本身包括文档和一个lib (jaas.jar)
在windows系统中, 这些类库被命名为 $JAVA_HOME\jre\bin\jaas_nt.dll
JAVA沙箱
安全模型的关键在于沙箱(sandbox)的概念. 其思想是, 若在你的主机上允许驻留一个程序, 你就必须为该程序提供一个场所(即运行环境), 但是你还希望为这个程序限定一个范围, 例如, 你想限制程序所能存取的系统资源等. 一般情况下, 必须保证程序限制在沙箱中.
Java沙箱负责保护一些系统资源, 而且保护级别是不同的.
沙箱的模式并非一种, 沙箱范围的扩展往往建立在信任的基础上. 有些情况下, 我相信这些程序, 因此允许它们访问我的文件系统, 但有些情况下, 我只允许它们访问部分文件, 也有可能这些程序根本不值得我信任, 因此我将禁止它们访问我的文件系统.
Java的安全策略包括:
l 字节码校验器(bytecode verifier)
字节码校验器可以确保java类文件遵循java语言规则. 从资源的角度来看, 字节码校验器可以帮助所有 java程序实现内存保护. 并非所有 的类都要通过字节码校验.
l 类装载器(class loader)
所有java类都是通过一个或多个类装载器实现载入的. 类装载器可以程序你给的设置其载入的类的权限.
l 存取控制器(access controller)
存取控制器有句话(或禁止)核心API对操作系统的存取权限.这是基于策略面定的, 而策略则由终端用户或系统管理员设置.
l 安全管理器(security manager)
安全管理器是核心API和操作系统间的主要接口.它是对系统资源存取控制的最后一道防线.
l 安全软件包(security package)
java.security包相关的安全扩展包中的类允许你为自己的应用增加新的安全特性. 在此基础上, 可以实现 java类的签名.具体包括:
n 安全提供者(security provider)接口, 通过此接口, 可以把不同的安全实现直接插入到安全软件包中.
n 消息摘要
n 密钥与证书
n 数字签名
n 加密(通过JCE和JSSE)
n 鉴别(通过JAAS)
l 密钥数据库.
密钥数据库管理的是在安全基础设施中所用到的密钥. 可以用它们创建或验证数字签名. 在java体系结构中. 它属于安全软件包的一部分. 但只可以表示为一个外部文件或数据库.
以上最后的两项的应用面很广, 并不局限于沙箱应用. 对于沙箱而言, 数字签名是作用相当重要, 因为数字签名可以作为鉴别依据, 以证实是谁提供的java类.
安全调试
Java安全软件包中包含有高度代码, 通过 设置系统属性可以使之处于调试状态下
属性Java.security.debug
选项:
l all 打开所有调试选项.
l Access 跟踪所有对存取控制器checkPermission()方法的调用, 从而可以查看代码中需要哪些权限. 即那些调用成功了, 那些调用失败了.
此选项还可以继续分为以下几个子选项(如果未专门指定, 则所有子选项均有效):
n Stack 一旦检查到一项权限, 即置空栈.
n Failure 只有在权限遭到拒绝时才置空栈.
n Domain 检查到一项保护时即置保护域为空
l Jar 当处理一个签名的jar文件时在文件, 证书及所应用的类中分别写入签名.
l Policy 在解析时打印关于策略文件的信息,
l Scl 打印直接由安全类装载器(而不是策略文件)授权的权限信息.
选项间可以用逗号间隔
例如 要查看由安全类装载器授权的权限, 同时还要跟踪权限检查失败情况下栈的变化情况, 就要在命令行中将选项参数指定为–Djava.security.dcbug=scl,access,failure
JSSE通过访问javax.net.debug属性扩展了此功能, 其选项包括:
l All 打开所有选项及子选项.
l Ssl 打开ssl调试. 该选项可进一步分为以下子选项(若示指定, 则均有效):
n Record 打印对每个ssl记录的跟踪情况(在SSL协议层)
n Handshake 打印为私有密钥交换而建立的密钥生成数据.
n Session 打印SSL会话行为信息.
n Defaultctx 打印默认的SSL初始化信息
n Sslctx 打印SSL上下文信息.
n Sessioncache 打印关于SSL会话缓冲的信息.
n Keymanager 打印关于对密钥管理器的调用情况信息.
n Trustmanager 打印对可信管理器的调用情况信息.
n Data 为了实现对握手的跟踪, 打印所有消息的十六进制转储信息.
n Verbose 打印握手的详细跟踪情况信息.
n Plaintext 为了跟踪记录, 打印记录的十六进制转储信息.
Java沙箱的要素
沙箱包括5个要素:
l 权限(permission)
指允许代码执行的具体操作. 权限本身包括三个要素: 权限类型, 权限名及允许的操作. 尽管管理默认沙箱不需要再编写程序, 但管理员不是有必要了解不同的权限所对应的java类名, 这样才能正确地调用代码以实现操作.
权限类型实际上是一个实现权限的Java类名.一般情况下, 需要基于权限类型设置相应的权限名. 权限操作指定了对目标可以执行的操作行为, 如文件权限可以指定对某个文件可读, 可写或可删除.
例:
permission java.security.AllPermission;
permission java.lang.RuntimePermission “stopThread”;
permission java.io.FilePermission “/tmp/foo”, “read”;
l 代码源(code source)
代码源是类所在的位置, 若对类做了签名, 则签名者的信息也在代码源处保存. 该位置被指定为URL地址,代码可以基于文件的URL从文件系统获得, 也可以通过基于网络的URL从网络上获得.签名不是必须的, 一般称代码源中的URL为代码基(codebase).
l 保护域(protection domain)
将代码源的权限进行组合而建立的.保护域是默认沙箱中的基本概念, 例如: 由某个保护域我们可知道:由www.oreilly.com得到的代码可以读软盘上的文件,由www.klflote.com得到并由scott签名的代码可以做任何工作.
l 策略文件(policy file)
策略文件是控制沙箱的管理要素. 策略文件包括一个或多个定义保护域的项. 通常我们认为是策略文件中的项完成了代码权限的指定任务, 这里往往需要指出代码装载的地址或者代码签名者的信息.
在程序中定义特事特办文件的方式有多种, 但通常使用的只有两类策略文件: 全局策略文件和用户专用的策略文件, 其中全局策略文件作用于虚拟机中使用的所有实例. 策略文件可以用文本编辑器对其进行创建各修改, 同时 JRE还提供 了一个工具policytool去维护策略文件.
l 密钥库(keystore)
代码签名只是实现授权的一种方式, 通过这种方式可以完成多层次的授权. 代码签名需要基于公开密钥证书(publickey certificate)证书本身通常保存在文件中, 保存证书的位置被称为密钥库. 作为开发人员, 如果想对代码签名, 就要有相应的证书, 而要获得证书就需要访问密钥库.如果是终端用户或系统管理员, 运行签名的代码时, 则需要查找密钥库从而获知相应的签名者的情况.