数字签名常被用来校验软件及软件制造者以保证软件代码没有被任何方式
玷污
或者通俗地讲使用数字签名可以确保软件的清洁和正宗即软件
从其制造者或出版商处直到最终用户手中这段时间里未被他人篡改过
本文在对数字签名的有关概念进行简单回顾后给出了用JAVA来创建和使用
数字签名的具体方法
一数字签名及其功能
数字签名算法(DSA) 是公共密钥加密算法中的一种因此让我们从
私有密钥/公共密钥开始进行简单回顾
私有密钥加密及其局限性
私有密钥加密系统使用唯一的密钥(即私有密钥)进行加密和解密该密钥
必须为发送者和接收者所共享即若甲要向乙发一个加密邮件甲需用一密钥
将信息加密乙收到邮件后须用同样的密钥将信息解密
该方法显然有非常严重的缺点例如接收双方必须拥有同样的密钥这要
求一定要有一种安全的协议来保证密钥传送的可靠第二有紧急的加密消息需
要发送时可能因接收方没有密钥而不能完成传送第三若要将消息发给许多
不同的团体就需要与各个团体对应维护许多不同的密钥
为克服私有密钥加密系统的这些弱点人们引进了公共密钥加密系统
公共密钥加密
公共密钥加密不需要一条信息的发送者和接收者知道对方的密钥就能访问
该加密信息
公共密钥加密系统使用密钥对(公共密钥和私有密钥)来加密和解密信息
其加密思想也非常简单用公共密钥加密的信息只能用与之对应的私有密钥解开
而用私有密钥加密的信息任何拥有与之对应的公共密钥的人均可解开因此私
有密钥总为个人保管而无须外传公共密钥则可授权给他人使用而不会破坏安全
性公共密钥和私有密钥之间永远存在着一对一的关系具体地讲即
第一若信息是用接收方的公共密钥加密的则只有应该收到此消息的人
才能对之解密(即只有拥有与该公共密钥对应的私有密钥的人才可解密)例如
甲要向乙发一个加密邮件甲必须用乙的公共密钥加密信息后再传给乙
第二若信息是用发送方的私有密钥加密的则任何拥有发送方公共密钥的
接收者都可以对信息进行解密从而确定该信息确实是来自该发送者并且信息
内容未遭到任何无意或恶意的破坏
上述第二点正是数字签名的含义
数字签名的功能
一个数字签名是一个定长的二进制数字流其内容附着于被签名的数据之上
它可以和任何种类的数字数据一起使用除最普通的代码软件外还可用在口令
电子邮件及电子文档中数字签名的主要功能为防止原始文档被污染或变更
防止别有用心者使用他人名字散布欺骗性消息以及提供谁是文件原作者的证
据等等
二用JAVA创建及使用数字签名
除了上面提到的功能外用JAVA做数字签名还有更现实的意义最常见的是
应用数字签名可以突破浏览器在安全性方面的某些限制例如你的浏览器一般
会拒绝网上的JAVA程序读写你本地硬盘的文件或获取你的本地信息(如你的用户
名称等)哪怕你确认该JAVA程序是可靠的(其实你不可能完全确认来自网
上的某个程序真的是可靠的)若你确要运行该JAVA程序你必须关闭浏览
器的安全检查功能但这无异于将本地系统置为不设防的城池使用数字签
名可完美地解决这个问题当浏览器感觉到你使用的是签名后的JAVA小程序后
它会自动搜索与之匹配的数字签名并进行校验若成功则浏览器认定该JAVA小程序
是值得信任的于是放行这样既保证了安全性又可以让真正可信的的JAVA程序拥有许多特权(见下述JAVA程序)
在 JDK 中与数字签名有关的工作是由工具程序 javakey 来完成的
javakey 是 Sun 提供的一个命令行工具用来为存档文件(jar 文件)生成数
字签名并管理密钥数据库
下面我们将通过一个具体例子来看一看创建和使用数字签名的步骤有关概
念和解释将在例子中给出
Java 程序及数字签名的创建 (加密方或签字者应执行的步骤)
下面的JAVA小程序非常简单它的主要功能为获取 Win/系统当前登录
用户的名称字符串然后将之写入本地硬盘当前目录的 TestTxt 文件上
import javaawt*;
import javaio*;
import javalang*;
import javaapplet*;
public class MyApp extends Applet {
DataOutputStream out_file;
public void paint(Graphics g) {
try {
String YourName = SystemgetProperty(username);
out_file = new DataOutputStream(new FileOutputStream(TestTxt));
out_filewriteChars(Your Name: +YourName+\n);
out_fileclose();
gdrawString(Your Name has been written to file );}
catch (IOException e) {
gdrawString(File i/o error );
}
catch (SecurityException se) {
gdrawString(You can NOT write to disk or get User Name );
}
}
}
// End of MyAppjava
将 MyAppjava 编译为 MyAppclass 后用下面的 l 送往浏览器
(命令为 appletviewer l)
/* End of l */
我们发现浏览器上显示的是You can NOT write to disk or get User Name
这是因为获取用户名和写本地硬盘均是系统安全特性所禁止的
下面我们创建一个数字签名以便该程序的使用者无须变更浏览器的安全检查
特性就能完成程序功能(即读用户名写入文件)
第一步创建一个实体并将之设为可信的
javakey cs Kompass true
此处的实体是指签字者(个人公司或组织)这里假定为Kompass参
数cs告诉 javakey创建一个签字者并将之放入数据库中(不带参数运行javakey
将得到详细帮助信息)可选参数true表示签字者Kompass是可信
的(缺省值是不可信)
第二步生成密钥对(公共密钥和私有密钥)并输出至文件(可选)
javakey gk Kompass DSA Kompass_pub Kompass_priv
其中DSA是加密算法的名字是密钥的长度Kompass_pub
Kompass_priv分别是两个密钥输出文件的名字
第三步生成一个许可证(certificate)
javakey gc cert_directive_Kompass
这里的许可证即为可以交给接收方的数字签名
上面的参数cert_directive_Kompass并不是输出文件名而是一个缺省
参数配置文件名通俗地讲它象是一个ini文件javakey 根据该文件的
内容决定如何生成一个许可证因此签字者在执行本步骤之前必须用文本编辑
器先生成这个配置文件(学名叫指示文件directive file)
以下给出文件 cert_directive_Kompass 的内容
issuername=Kompass
issuercert=
subjectname=Kompass
subjectrealname=Kompass
unit=JavaSoft
=Sun MicroSystems
untry=US
startdate= May
enddate= May
serialnumber=
outfile=Kompasskey
/* End of cert_directive_Kompass */
从上面最后一行可以看出输出文件的名字被定义为Kompasskey即
数字签名Kompasskey连同签字后的文件将一同被发给接收者
上述文件包括的其它信息主要有发行者信息(issuer)主题信息
(subject)许可证信息(有效期限及序列号)等
第四步创建存档文件( jar 文件)
jar cf signMyAppjar MyAppclass l
这里需要说明的是jar是 Sun提供的另一个命令行工具用于生成和维护
存档文件( jar 文件) jar是一个打包工具它可将JAVA小程序连同有关的
声音图像动画等文件一起打包成一个文件以便于JAVA产品