Java技术的设计人员在一开始就关注到了关于语言的安全问题。相较于其他语言,Java的安全机制是该语言不可分割的一部分,是提前被想到并且实现的。Java语言提供了以下三种确保安全的机制:
语言设计特性(数组边界,类型转换,空指针)
访问控制机制(控制代码能够执行的操作,访问文件等等)
代码签名(认证该代码来自哪里)
下面我们首先了解类加载器和类加载机制,类加载器可以在类加载到虚拟机时检测其是否被损坏。Java语言为了获取最大的安全控制,通常无论是普通的类加载器或者是自定义的类加载器,都需要与安全管理器类协同工作。
类加载器与加载过程
我们编写的Java文件一开始都是.class类型的,当该文件被编译后(被一个程序解释)成为Java文件,在JVM虚拟机上运行。虚拟机只会加载程序执行时所需要的类文件。例如一个test.class文件,首先从磁盘开始读取,如果该文件中还是用了其他的父类或者调用了更多的类,则加载其他类的文件(该过程被称为类的解析)。接着,虚拟机优先执行main方法(main为静态方法),如果main方法中还在调用其他类,则接下来就去加载这些类。
以上这些操作,并不只是单个类加载器就能完成的,每个Java程序至少拥有三个类加载器:
引导类加载器:负责加载系统类,通常在jar文件中进行加载,是虚拟机不可分割的一部分,并且通常使用c语言进行实现,引导类加载器没有其对应的classLoader对象
扩展类加载器:用于从jar/lib/ext 目录加载文件
系统类加载器(应用类加载器):用于加载应用类,在由classpath环境变量或者-classpath命令行选项设置的类路径中的目录里或者是JAR/ZIP文件中查找这个类
这些类加载器存在一种父子关系,除了引导类加载器,每个类加载器都有一个父类加载器,那两个类加载器会在加载一个类前,先给其父类加载器一个机会,只有父类加载器无法加载时,会交给类加载器。
数字签名
在此之前我们先要对applet有一个大致的了解。applet是Java语言编写的小应用程序,该程序可以包含在HTML页面中。applet在Java平台上开始逐渐流行,人们逐渐开始意识到,要使applet开始流行并且变得非常有用,用户必须根据其来源分配不同的安全级别,如果applet来自值得信赖的提供商并且没有在传播途中被篡改,那么用户就可以去考虑是否给予此程序更多的权限。在过去的几十年中,已经出现不少成熟的算法来确保数据和电子签名的完整性,在java.security包中包含了许多这类算法的实现。
消息摘要是数据块的数字指纹,所谓数字指纹,就是对于文件通过算法生成的特定密码,不论文件的大小,都可以被压缩至160(20字节)位的序列。常见的有SHA1,MD5等加密算法。可生成的密码数量巨大,无需担心不同的文件最终生成相同的指纹(生成相同指纹的概率相当于认识的六个人同时掉进坑里)。我们可以通过MessageDigest对象来获取到加密算法,对数组文件进行加密,并且加密结果以字节数组的形式进行返回
/**
* @author Anderson
* 对加密算法进行测试
*/
public class SecurityTest {
public static void main(String[] args) throws NoSuchAlgorithmException {
byte[] bytes={'H','E','L','L','O','!'};
MessageDigest digest=MessageDigest.getInstance("SHA-256");获取计算SHA-256指纹的对象
digest.update(bytes);//更新数组
byte[] hash=digest.digest();//按照指纹算法补齐输入,并进行相应的计算
for(byte b:hash){
System.out.println(b);
}
}
}
可是,即使可以做到不会出现相同的指纹,对于文件进行篡改,依然可以在篡改后生成新的指纹,然后将被篡改的文件和相应的指纹发送出去,接收者依然无法判定该文件是否被恶意篡改。为此,数字签名很好的解决了这个问题。在了解数字签名工作原理之前,我们需要了解一下公共密钥加密技术,他是基于公共密钥和私有密钥两个基本概念产生,我们需要做到保护好自己的私有密钥而可以将公共密钥交给任何人。两个密钥之间存在某种数学关系,但是却无法被攻破。这样就可以变成:A发送给B文件,A在文件上使用私有密钥进行了签名,B获取了A的公有密钥,使用其对签名进行校验,最终可以确定
原始消息没有被篡改
该消息是A发送而来
前提是私有密钥没有被泄露
但是认证问题又出现了,假如一个声称自己是A的人给B发送了附带公共密钥的软件希望你下载运行。这时仍然要小心,因为你完全不知道A是否是本人,陌生人依然可以生成私有密钥和公有密钥并且对文件进行签名。解决此问题最简单的办法就是找到一个双方都认可的中间人。(最著名的中间人为VeriSign公司)
但是事实上,你也不应该对于中间人保有太大的期望,毕竟VeriSign公司的CEO不会去会见自己的每一位顾客,有些证明完全可以花点钱在该公司的网站上进行获得。申请者依然可以随便填写。因此,当你收到一份经过验证的消息时,重要是要明白它实际上认证了什么。