深入理解java虚拟机读书笔记之-----安全(2)

来源:互联网 发布:绝缘电阻数据怎么填 编辑:程序博客网 时间:2024/05/29 16:05
代码签名和认证
    Java安全模型很重要的一点就是它能支持认证。认证可以使用户确认,由某些团体担保的一些class文件是值得信任的,并且这些class文件在到达用户虚拟机的途中没有被改变。
    
    要对一段代码作担保或者签名,必须首先生成一个公钥/私钥对。用户应该保管那把私钥而把公钥公开。至少,应该把公钥给那些要在你的签名上建立安全策略的人。一旦拥有了一个公钥/私钥对,就必须将要签名的class文件和其他文件放到一个JAR文件中,然后使用一个工具(例如版本1.2 SDK中的jarsigner)对整个JAR文件签名。这个签名工具将首先对JAR文件的内容进行单向散列计算,以产生一个散列。然后这个工具将用私钥对这个散列进行签名,并且将经过签名后的散列加到JAR文件的末尾。这个签名后的散列代表了你对这个JAR文件内容的数字签名。当你发布这个包含签名散列的JAR文件时,那些持有你的公钥的人将对JAR文件验证两件事:这个JAR文件确实是你签名的,并且在你签名后这个JAR文件没有做过任何改动。
    散列也被称为消息文摘,它相当于一种输入“指纹”。
    单向散列算法是从大量数据(输入)中产生少量数据(消息摘要或者散列),所以不同的输入可能产生相同的散列。单向散列算法倾向于充分随机地分布产生相同散列的输入,从而使产生相同散列值的概率主要依赖于散列的大小。
    (注:关于数字签名、数字证书、非对称加密算法、证书管理工具的一些基础知识,原来的一篇文章简单整理过,见小蚂蚁-CAS单点登录系列(1)-基础知识)


 
    要认证一个已签名的JAR文件,接收者必须用公钥对签名散列进行解密,得到的结果应该和从JAR文件计算而得到的散列值相等。


  
 
一个代码签名示例
1)测试环境
Windows 7 + JDK 1.6
 
2)示例代码
一个接口两个类:
Java代码  收藏代码
  1. package com.artima.security.doer;  
  2.   
  3. public interface Doer {  
  4.     void doYourThing();  
  5. }  
 
Java代码  收藏代码
  1. package com.artima.security.friend;  
  2. import com.artima.security.doer.Doer;  
  3. import java.security.AccessController;  
  4. import java.security.PrivilegedAction;  
  5.   
  6. public class Friend implements Doer {  
  7.   
  8.     private Doer next;  
  9.     private boolean direct;  
  10.   
  11.     public Friend(Doer next, boolean direct) {  
  12.         this.next = next;  
  13.         this.direct = direct;  
  14.     }  
  15.   
  16.     public void doYourThing() {  
  17.   
  18.         if (direct) {  
  19.             next.doYourThing();  
  20.         }  
  21.         else {  
  22.             AccessController.doPrivileged(  
  23.                 new PrivilegedAction() {  
  24.                     public Object run() {  
  25.                         next.doYourThing();  
  26.                         return null;  
  27.                     }  
  28.                 }  
  29.             );  
  30.         }  
  31.     }  
  32. }  
 
Java代码  收藏代码
  1. package com.artima.security.stranger;  
  2. import com.artima.security.doer.Doer;  
  3. import java.security.AccessController;  
  4. import java.security.PrivilegedAction;  
  5.   
  6. public class Stranger implements Doer {  
  7.   
  8.     private Doer next;  
  9.     private boolean direct;  
  10.   
  11.     public Stranger(Doer next, boolean direct) {  
  12.         this.next = next;  
  13.         this.direct = direct;  
  14.     }  
  15.   
  16.     public void doYourThing() {  
  17.   
  18.         if (direct) {  
  19.             next.doYourThing();  
  20.         }  
  21.         else {  
  22.             AccessController.doPrivileged(  
  23.                 new PrivilegedAction() {  
  24.                     public Object run() {  
  25.                         next.doYourThing();  
  26.                         return null;  
  27.                     }  
  28.                 }  
  29.             );  
  30.         }  
  31.     }  
  32. }  
 
附件附带了源代码:samples.zip
 
3)编译java文件
javac com\artima\security\doer\Doer.java
javac com\artima\security\friend\Friend.java
javac com\artima\security\stranger\Stranger.java
 
4)打包class文件
jar cvf friend.jar com\artima\security\friend\*.class
jar cvf stranger.jar com\artima\security\stranger\*.class
 
5)删除class文件
删除class文件,以便Java虚拟机在运行后面的访问控制的例子时无法找到它:
del com\artima\security\friend\*.class
del com\artima\security\stranger\*.class
 
6)生成密钥对并进行存储
6.1)生成friend的密钥对
命令:keytool -genkey -alias friend -keypass friend4life -validity 10000 -keystore ijvmkeys
keystore密码:ijvm2ed
其他参数:
java
sun
sun
gz
gd
cn
y
 
(注:其中friend为密钥别名,friend的主密码为friend4life,有效期为10000天,keystore文件名为ijvmkeys。)
 
6.2)生成stranger的密钥对
命令:keytool -genkey -alias stranger -keypass stranger4life -validity 10000 -keystore ijvmkeys -storepass ijvm2ed
参数:
java
sun
sun
gz
gd
cn
y
 
(注:storepass直接指明了1)中设置的keystore密码)
 
7)现在keystore文件ijvmkeys包含了friend和stranger的密钥对,下面对JAR文件进行签名
jarsigner -keystore ijvmkeys -storepass ijvm2ed -keypass friend4life friend.jar friend
jarsigner -keystore ijvmkeys -storepass ijvm2ed -keypass stranger4life stranger.jar stranger
 
好了,为了对两个JAR进行签名,必须做上面这许多事。