《深入java虚拟机二》之安全tips

《深入java虚拟机2》之安全tips
发现有这么一本书在书架上,随便翻翻。

1.java的安全模型包括类装载体系、class文件4重校验、java内置安全特性、安全管理器和java api.

2.java类装载体系通过4个措施预防安全问题。
  (1)同一个命名空间(package)下只能加载一个相同类名的类。
  (2)委托父装载器优先加载防止非受信任类先于受信任类加载。
  (3)位于相同命名空间下(package)的类,jvm只授予使用相同classloader加载类具有包访问成员的权限。所以不要认为自定义一个java.lang.Virus就能够访问到java.lang下protected的成员或者包访问权限的成员。
  (4)黑名单策略,限定某些包可以加载。

3.class文件的4重校验。
 (1).class文件的结构检查,主要是校验文件本身的写作是否满足class文件的固定格式。
 (2).类型数据的语义检查,比如方法描述符(返回类型,参数类型和个数)字符串必须符合特定的上下文无关文法。
 (3).字节码验证,检查每一个字节码集合是否符合一个特定的规则集合。
  (4).符号引用验证,当一个class文件被加载的时候,它包含了对其他类的符号引用以及他们的字段和方法,jvm执行字节码时,如果遇到一个操作码,这个操作码第一次使用一个指向另一个类的符号引用,那么jvm必须解析这个符号引用,具体的操作包括1'查找被引用的类(还没装载就装载起来)2'将符号引用替换为直接引用,即将这个字符串替换为执行类、字段或者方法的指针或者偏移量。

4.java内置的安全特性
 (1).类型安全引用转换
  (2).结构化内存访问
  (3).gc
  (4).空引用检查

5.安全管理器
  java代码执行级别的权限控制,判定某个操作是否可以执行。具体的策略定义在一个固定文件中。但是貌似大家都不怎么用这个安全管理器,唯一使用的是AccessController.doPrivileged,而这个操作意图竟是使某些敏感执行绕过安全策略。
 
6.代码签名和认证
 java对于代码(class文件或者jar文件)输入进行散列计算,得到的散列值相当于这个代码的"指纹",发布后使用这份代码的时候,只要按相同算法对代码进行散列计算,得到散列值与原始散列值相同即认为代码没有在中间被篡改。但是存在一个问题是,原始输入和散列能够被很方便的替换掉,也能通过认证。那么可选择的应对方案就是对代码进行私钥加密,公钥解密。不过因为私钥对代码加密可能时间耗费比较久,就只对代码的散列进行私钥加密。在只有公钥的情况下要得到私钥是非常困难的,所以这种方案是比较安全的防篡改方式。除非另外一个输入产生的散列值和原始输入的散列值相同,那么私钥也不需要了,但是这个可操作性是比较低的,一个是因为原始输入包含大量数据,并且散列值就算是8位也有256种可能(2的8次方),普遍采用的64位和128位散列则有更多的可能。
 代码签名并不会对代码(class文件或者jar文件)进行加密,所有人都可能看见,而这个操作的意义在于让使用者准确判定这份代码有没有被中间篡改,从而确保代码执行按照可信任的作者意图安全执行。