深入理解Java虚拟机读书笔记之:第3章 安全(2)
程序员文章站
2022-06-24 23:54:19
...
代码签名和认证
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)示例代码
一个接口两个类:
package com.artima.security.doer; public interface Doer { void doYourThing(); }
package com.artima.security.friend; import com.artima.security.doer.Doer; import java.security.AccessController; import java.security.PrivilegedAction; public class Friend implements Doer { private Doer next; private boolean direct; public Friend(Doer next, boolean direct) { this.next = next; this.direct = direct; } public void doYourThing() { if (direct) { next.doYourThing(); } else { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { next.doYourThing(); return null; } } ); } } }
package com.artima.security.stranger; import com.artima.security.doer.Doer; import java.security.AccessController; import java.security.PrivilegedAction; public class Stranger implements Doer { private Doer next; private boolean direct; public Stranger(Doer next, boolean direct) { this.next = next; this.direct = direct; } public void doYourThing() { if (direct) { next.doYourThing(); } else { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { next.doYourThing(); return null; } } ); } } }
附件附带了源代码: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进行签名,必须做上面这许多事。
(转载请注明来源:http://zhanjia.iteye.com/blog/1842242)
上一篇: TCP协议之网络延时