一、简介
Java语言和其他语言有所不同,在其他语言中安全是在事后才想到要去实现的,或者仅仅是对破坏的一种应对措施,而对Java技术来说,安全机制是一个不可分割的组成部分。
Java提供了以下几种安全机制:
1、语言设计特性(类型转换的检查、无指针操作、对数组的边界进行检查)
2、访问控制机制。可以控制代码能够进行的操作(文件访问、网络访问等)
3、代码签名。利用此特性代码的作者可以使用标准的加密算法来认证Java代码。这样,代码的使用者就可以准确的知道谁创建了该代码,以及代码被签名之后是否被修改过。
二、类加载器
Java编译器将 .java后缀的文件转换为 .class为后缀的虚拟机指令,类加载器负责将 类文件加载到虚拟机中。
虚拟机只加载程序执行时所需要的类文件,假设程序从MyProgram.class开始运行,下面是虚拟机执行的步骤:
1、虚拟机有一个加载类文件的机制,它使用该机制来加载MyProgram类文件中的内容
2、如果 MyProgram类拥有一个 其他类型的域或者是 超类,那么对应的类和超类都会被加载(类的解析:加载某个类所依赖的所有类的过程)
3、执行MyProgram的main方法,如果main方法中需要更多的类,则 会继续加载这些类
类加载机制使用多个类加载器,每个Java程序至少拥有三个类加载器:
1、引导类加载器:加载Java系统类(通常rt.jar文件中进行加载),是虚拟机不可分割的一部分,通常用C语言实现,没有对应的ClassLoader对象
2、扩展类加载器:用于从 jre/lib/ext目录加载 “标准的扩展”,可以将JAR文件放入该目录,这样即使没有指定任何类路径,扩展类加载器也可以找到其中的各个类。
3、系统类加载器:从 环境变量CLASSPATH或者-classpath命令 指定的类路径中查找类
三、类加载器的层次结构
类加载器有 父/子关系,除了引导类加载器之外,每个类加载器都有一个父类加载器。 根据规定,类加载器会为 父类加载器提供一个机会,让父类加载器去加载任何给定的类,只有当父类加载器加载失败时,子类才会去加载对应的类。
例如:当要求系统类加载器加载一个Java系统类(例如ArrayList,而这本该是 引导类加载器的工作)时,它首先要求扩展类加载器加载,而扩展类加载器则要求引导类加载器加载,引导类加载器查找并加载 rt.jar中的类,无需其它类再做出查找
四、将类加载器作为命名空间
Java包的存在是为了减少类命名的冲突。在同一个虚拟机中,可以有两个类,他们的类名和包名都是相同的,因为在虚拟机中,类是由它的 全面和类加载器 来确定的,这项技术在加载来自多出的代码时很有用。
五、字节码校验
当类加载器将新加载的Java平台类的字节码传递给虚拟机时,这些字节码首先要接收 校验器的 校验。
校验器负责检查那些 明显有破坏性的操作。
除了系统类之外,其余所有的类都必须要被校验。
校验器执行的一些检查:
1、变量使用之前要进行初始化
2、方法调用与对象引用类型之间要匹配
3、访问私有数据和方法的规则没有被违反
4、对本地变量的访问都落在运行时堆栈内
5、运行时堆栈没有溢出等
如果以上这些检查的任何一条没有通过,就认为该类遭到了 破坏,不予加载。
六、安全管理器
一旦某个类被加载到虚拟机中,并由校验器检查过之后, 接下来的安全 由 安全管理器负责。安全管理器是一个负责控制具体操作是否允许执行的类。
负责检查的操作包括以下内容:
1、创建新的类加载器
2、退出虚拟机
3、使用反射访问另一个类的成员
4、访问本地文件
5、打开socket连接
6、启动打印作业
7、访问系统剪贴板等
运行Java应用程序时,默认 不安装 安全管理器,这样所有的操作都是允许的。但是在需要从 某个网络地址加载类文件时就需要打开安全管理器,并配置相应的 安全策略。
七、消息摘要
消息摘要是 数据块的数字指纹。SHA和MD5算法都可以用于计算消息摘要。
消息摘要具有两个基本属性:
1、如果数据的一位或者几位改变了,那么消息摘要也将改变
2、拥有消息摘要 的伪造者 无法还原 原本的消息
实际上,因为消息摘要的长度都是固定的,所有有可能出现重复,但是可能性非常低。
Java已经实现了SHA和MD5算法,使用 MessageDigest类的静态的getInstance()方法,可以获取到对应的 计算SHA或者MD5的对象。
八、消息签名(这个消息确实是你发的,并且没有被篡改过)
消息摘要使用公开的算法对 消息生成MD5,因此如果我们 截获一个消息,修改之后生成新的MD5并和消息一起发送出去,接收方拿到消息时发现消息和MD5是符合的,但是其实 消息已经被篡改了。
数字签名解决了这个问题。以下为使用DSA(一种加密算法,类似的还有 RSA)进行数字签名和校验的步骤。
消息和私钥一起使用 签名算法 生成签名,接收者将 消息、签名配合公钥一起使用 校验算法 进行校验
九、加密(明文变密文)
对称加密:加密和解密使用相同的密钥。 致命缺点在于 密码的分发,如果 一个端改变了密码,就需要使用很安全的方式把密钥也发给 对方。 优点在于:速度很快,可以加密大量的信息。
非对称加密:一个公共密钥和一个相匹配的私有密钥。使用公共密钥进行加密,然后使用私有密钥进行解密。 优点在于:不用考虑密钥的分发 。缺点:一致的算法的操作速度比对称加密算法慢很多,对大量的信息进行加密不切实际。
更优的方式:
二者相结合,使用对称密钥对明文进行加密,再使用非对称密钥对 对称密钥进行加密,后将二者一同发出。接收方是有自己的私钥对 对称密钥 进行解密,之后使用 对称密钥对密文进行解密。