用JAVA做数字签名

  数字签名常被用来校验软件及软件制造者,以保证软件代码没有被任何方式玷污。
  ----或者通俗地讲,使用数字签名可以确保软件的“清洁”和“正宗”,即软件从其制造者或出版商处直到最终用户手中这段时间里未被他人篡改过。
  ----本文在对数字签名的有关概念进行简单回顾后,给出了用JAVA来创建和使用数字签名的具体方法。
  一、数字签名及其功能
  ----数字签名算法(DSA)是“公共密钥加密算法”中的一种,因此让我们从“私有密钥/公共密钥”开始进行简单回顾。
  ----1.私有密钥加密及其局限性
  ----私有密钥加密系统使用唯一的密钥(即私有密钥)进行加密和解密。该密钥必须为发送者和接收者所共享。即,若甲要向乙发一个加密邮件,甲需用一密钥将信息加密;乙收到邮件后,须用同样的密钥将信息解密。
  ----该方法显然有非常严重的缺点。例如,接收双方必须拥有同样的密钥,这要求一定要有一种安全的协议来保证密钥传送的可靠;第二,有紧急的加密消息需要发送时,可能因接收方没有密钥而不能完成传送;第三,若要将消息发给许多不同的团体,就需要与各个团体对应,维护许多不同的密钥。
  ----为克服私有密钥加密系统的这些弱点,人们引进了公共密钥加密系统。
  ----2.公共密钥加密
  ----公共密钥加密不需要一条信息的发送者和接收者知道对方的密钥,就能访问该加密信息。
  ----公共密钥加密系统使用密钥对(公共密钥和私有密钥)来加密和解密信息。其加密思想也非常简单:用公共密钥加密的信息只能用与之对应的私有密钥解开;而用私有密钥加密的信息,任何拥有与之对应的公共密钥的人均可解开。因此,私有密钥总为个人保管而无须外传,公共密钥则可授权给他人使用而不会破坏安全性,公共密钥和私有密钥之间永远存在着一对一的关系。具体地讲即:
  ----第一,若信息是用接收方的公共密钥加密的,则只有应该收到此消息的人才能对之解密(即只有拥有与该公共密钥对应的私有密钥的人才可解密)。例如,甲要向乙发一个加密邮件,甲必须用乙的公共密钥加密信息后再传给乙。
  ----第二,若信息是用发送方的私有密钥加密的,则任何拥有发送方公共密钥的接收者都可以对信息进行解密,从而确定该信息确实是来自该发送者,并且信息内容未遭到任何无意或恶意的破坏。
  ----上述第二点正是数字签名的含义。
  ----3.数字签名的功能
  ----一个数字签名是一个定长的二进制数字流,其内容附着于被签名的数据之上。它可以和任何种类的数字数据一起使用,除最普通的代码软件外。还可用在口令、电子邮件及电子文档中。数字签名的主要功能为:防止原始文档被污染或变更;防止别有用心者使用他人名字散布欺骗性消息;以及,提供谁是文件原作者的证据,等等。
  二、用JAVA创建及使用数字签名
  ----除了上面提到的功能外,用JAVA做数字签名还有更现实的意义。最常见的是:应用数字签名可以突破浏览器在安全性方面的某些限制。例如,你的浏览器一般会拒绝网上的JAVA程序读写你本地硬盘的文件或获取你的本地信息(如你的用户名称等),哪怕你确认该JAVA程序是“可靠的”(其实你不可能完全确认来自网上的某个程序真的是“可靠的”)。若你确要运行该JAVA程序,你必须关闭浏览器的安全检查功能,但这无异于将本地系统置为“不设防的城池”。使用数字签名可完美地解决这个问题:当浏览器“感觉”到你使用的是签名后的JAVA小程序后,它会自动搜索与之匹配的数字签名并进行校验,若成功则浏览器认定该JAVA小程序是“值得信任的”,于是放行。这样,既保证了安全性,又可以让真正“可信的”的JAVA程序拥有许多特权(见下述JAVA程序)。
  ----在JDK1.1中,与数字签名有关的工作是由工具程序javakey来完成的。javakey是Sun提供的一个命令行工具,用来为存档文件(jar文件)生成数字签名并管理密钥数据库。
  ----下面我们将通过一个具体例子来看一看创建和使用数字签名的步骤,有关概念和解释将在例子中给出。
  ----1.Java程序及数字签名的创建(加密方或签字者应执行的步骤)下面的JAVA小程序非常简单,它的主要功能为:获取Win95/98系统当前登录用户的名称字符串,然后将之写入本地硬盘当前目录的Test.Txt文件上。
  ......
  ----将MyApp.java编译为MyApp.class后,用下面的MyApp.html送往浏览器(命令为appletviewer MyApp.html)。
  ......
  ----我们发现浏览器上显示的是“You can NOT write to disk or get User Name”。这是因为获取用户名和写本地硬盘均是系统安全特性所禁止的。
  ----下面我们创建一个数字签名,以便该程序的使用者无须变更浏览器的安全检查特性就能完成程序功能(即:读用户名,写入文件)。
  ----第一步:创建一个实体,并将之设为“可信的”。
  ......
  ----第二步:生成密钥对(公共密钥和私有密钥)并输出至文件(可选)。
  ......
  ----第三步:生成一个许可证(certificate)。
  ......
  ----第四步:创建存档文件(jar文件)。
  ......
  ----第五步:对存档文件进行签名。
  ......
  ----第六步:更改文件名。
  ......
  ----2.数字签名的使用(解密方或使用者应执行的步骤)
  ----第一步:得到许可证(即数字签名--Kompass.key)和签名后的文件。
  ----第二步:创建签名者实体,并将之设为“可信的”。
  javakey-c Kompass true
  第三步:将许可证倒入数据库。
  javakey-ic Kompass Kompass.key
  最后一步:运行JAVA程序。
  appletviewer signMyApp.html
  我们注意到这里的“.html”
  不是上面给出的“MyApp.html”。其实这二者
  的差别很小,“signMyApp.html”
  只是多了一个参数:
  archive="signMyApp.jar"
  它告诉浏览器所有有用的文件
  (这里的MyApp.class)均在存档文件中而不
  在其它地方。
  ......
  ----现在,我们终于看到了期待已久的结果:浏览器打出了“Your Name has been written to file<Test.Txt>”;而文件“Test.Txt”确实被创建,并且其内容正是用户登录Win95/98时的名字:
  Y o u r N a m e:M a w e n q i a n