注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

民主与科学

独立之人格,自由之思想

 
 
 

日志

 
 

Java的数字签名和数字证书  

2011-09-07 17:11:04|  分类: 数字签名 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
本文部分整理编译自:深入java虚拟机第二版
注:关于数字证书部分,主要是我的一些推理。本人并没找到关于数字证书更详细的资料。
一、基本模型
   对于一个给定程序,如果我们能找到其作者,那么程序的作者就不敢编写夹带一些恶意的代码在里面。因为如果他编写夹带了恶意代码在里面,用户因此而造成任何损失的话,用户可以找到他,并可以起诉他。程序的作者必须对自己的程序负责。  通过使用数字签名和数字证书就可以达到这个目的。
    首先,要成立一些颁发和管理数字证书的公司或机构。如果有一个程序员或公司想开发一个程序,我们暂且称它们为开发者A
开发者A需要向一个数字证书公司或机构提交一些信息来请求该公司或机构对开发者A的程序进行担保。我暂且称数字证书公司或机构为数字证书机构B开发者A应该提供了足够的信息给数字证书机构B,以便数字证书机构B找到他。数字证书机构B给开发者颁发一个公钥/私钥对,中数字证书机构B用它自己的私钥(暂称为机构私钥B颁发的公钥进行加密对于私钥,我暂且称之为私钥BA对于公,我暂且称之为公钥BA对于该加密后的公钥BA(暂称为公钥BA1和其他的一些关于数字证书机构B的信息放在一个叫做数字证书的东西中我暂且称之为数字证书BA
    开发者A在他的程序(暂称为程序/JAR包C开发完成后,首先用对它的程序本身(class文件及资源)进行散列计算,得到散列值(暂称之为散列值D),用私钥BA对散列值进行加密。对于加密后的散列值我暂且称之为散列值D1。接着把散列值D1数字证书BA都加到程序/JAR包C中。这时候数字签名就完成了。开发者A就可以发布它的程序/JAR包C
    当有个用户(暂称之为用户E)得到了程序/JAR包C,并试图运行它。
第一步:这时JVM解压程序/JAR包C,发现里面有数字证书BA然后根据中的数字证书BA信息,在用户的系统中查找数字证书机构B钥(暂称为机构钥B),如果找到直接进入第三步,否则进入第二步
第二步JVM就从数字证书机构B中提取的机构钥B地址,告诉用户程序/JAR包C需要机构钥B并询问用户是在其地址否下载它。如果用户不信任该地址而不同意,试图运行程序/JAR包C失败。如果用户同意下载,但是下载失败的话,试图运行程序/JAR包C失败。如果下载成功就进入一步。
第三步JVM机构钥B数字证书BA中的公钥BA1进行解密计算得到公钥BA,然后用公钥BA散列值D1进行解密计算得到散列值D
程序/JAR包C本身内容(class文件及资源)进行散列计算,比较结果是否和散列值D一样。如果一样就说明程序/JAR包C的确是开发者A编写的,数字证书机构B为他进行了担保,并且在程序/JAR包C传输的途中并没有被窜改,验证成功,进入下一步。否则验证失败,就不能运行程序/JAR包C.如果验证成功,JVM就告诉用户程序/JAR包C来自于开发者A数字证书机构B开发者A的此程序进行了担保,并继续询问用户是否信任该程序。如果用户选择了不信任,那么试图运行程序/JAR包C失败。否则就开始运行程序/JAR包C
    如果在程序/JAR包C运行的过程,用户E发现它有一些恶意的行为;那么用户E可以通过机构钥B找到数字证书机构B,然后数字证书机构B通过程序/JAR包C中的数字证书BA找到公钥BA1,然后数字证书机构B可以通过公钥BA1来找到开发者A开发者A请求数字证书机构B开发者A的程序进行担保的时候,开发者A已经提供了足够的信息给数字证书机构B,以便数字证书机构B找到它当找到开发者A后,用户E数字证书机构B就可以向法院起诉开发者A了。如果严重的话,警察也会介入。开发者A必须对它的程序/JAR包C负责。
   因为程序的开发者必须对它的程序负责,所以他就不敢放一些恶意的代码在其程序中。
   数字签名和数字证书可以使用户确认,由某些团体担保的一些class文件是值得信任的,并且这些class文件在到达用户虚拟机的途中没有被改变。这样,如果用户在一定程度上信任这个为代码作担保的团体,也就可以在一定程度上简化沙箱对这段代码实施的限制。可以对由不同团体签名的代码建立不同的安全限制。理论上对于一个进行团体担保的程序,我们可以通过数字证书找到该程序的作者。
二、基本数字签名
     要对一段代码作担保或者签名,必须首先牛成一个公钥/私钥对程序员应该保管那把私钥,而把公钥公开。一旦拥有了一个公钥/私钥对,就必须将要签名的class 文件和其他文件放到一个JAR 文件中,然后使用一个工具(例如JDK中的jarSigner)对整个JAR 文件签名。这个签名工具将首先对JAR文件的内容进行单向散列计算,以产生一个散列。然后这个工具将使用私钥对这个散列进行签名,并将经过签名后的散列加到JAR文件的末尾。这个签名后的散列代表了你对这个JAR 文件内容的数字签名。当你发布这个包含签名散列的JAR 文件时,那些持有你的公钥的人将对JAR文件验证两件事:第一,JAR 文件确实是你签名的;第二,你签名后这个JAR 文件没有做过任何改动。
      数字签名过程的第一步是一个单向的散列计算它输入大量的数据,但产生少量的数据,称为散列。在这个JAR文件的例子中,这个计算的大量输人就是组成这个JAR 文件内容的字节流。这个单向散列计算之所以被称为“单向”,是因为在只给出散列(即那个少量的数据)的情况下,这个散列值不能包含足够的输人的信息,因此不能从散列重新生成原输人。
     散列也被称为消息文摘,它相当于一种输入“指纹”.虽然不同的输人可能产生相同的散列,但通常认为,在实际情况下,一个散列足以唯一标识产生它的输人。就像用指纹代表入一样,一个散列也被用于识别用单向散列算法产生这个散列的输人。在认证过程中,散列被用于验证某个输入是否和产生这个原始散列的输入相同、换句话说,这个输人在到达日的地的途中有没有被改动。
     数字签名过程的第二步是用私锁对散列值进行加密。但是散列本身可能被窜改。因此必须在发送散列前,用私钥对它进行加密。只加密散列而不是对整个JAR 进行加密,这是因为用私钥进行加密是一个相当费时的过程,而且只对散列加密就足够了。一般来说,从JAR 文件中计算、产生一个单项散列,并对这个散列用私钥进行加密,要比对整个JAR 文件用私钥进行加密来得快。只有当一个黑客拥有你的私钥时,他才能同时替换输入和其加密后的散列,因此要小心保存你的私钥,这样,相对于输人和散列组合,破解输人和加密散列组合就更困难了,因为黑客不可能拥有你的私钥。
     任何用你的私钥加密的东西都可以用你的公钥解密公钥/私钥对具有这种特点,在仅给出公钥的情况下时,想要产生私钥是非常困难的。如果黑客不能得到你的私钥,对他来说最好的选择就是试图将原输人替换为另一个输人,这个输人必须和原输人产生相同的散列值。例如,如果一个黑客想要在你的JAR 文件中将一个class文件替换成另一个执行恶意动作的class 文件.被修改的JAR 文件(包含了那个恶意的class 文件)产生一个和原散列一样的散列的几率是非常低的。但是这个黑客可以往JAR 文件中添加随机的数据,直到能产生和原来一样的散列值。如果黑客可以产生既能达到其邪恶目的,又能其散列值和原散列值一样的输入的话,它就不需要你的私锁。然而对干黑客来说,这样的方法会花去大量的时间,因此几乎是不可行的。
    因为单向散列算法是从大量数据(输人)中产生少量数据(消息摘要或者散列),所以不同的输人可能产生相同的散列:单向散列算法倾向于充分随机地分布产生相同散列的输人,从而使产生相同散列值的概率上要依赖于散列的大小。例如,如果使用了一个长8 位的散列值,散列算法最多产生256个不同的散列值。如果散列的位数越多,产生相同散列值的几率就越低。在实际情况中,普遍采用的是64 位或128 位的散列,通常认为这个长度已经足够了,这时想从不同的输人中产生一个相同的散列的计算是不可行的。因此防止黑客用恶意输人替换你的善意输入,并且产生相同散列值的主要障碍在于他必须花费大鳌的时间和资源才能找到这个恶意的输入。
    数字签名过程的第三步就是将这个加密后的散列值加到其JAR文件中在用私钥对散列值进行加密后,就需要将这个加密后的散列值加到其JAR文件中,在JAR文件中,除了输入源(class文件和数据文件),还包含你的已经加密后的散列值,还包含了你最初产生这个散列的文件。 其中加密的散列代表了你对JAR文件中的class类文件和数据文件的数字签名。图3-3显示了对一个JAR 文件进行数字签名的过程。
Java中的数字签名和数字证书 - hubingforever - 民主与科学
 
 验证一个已签名的JAR文件很简单。首先接收者用公钥对签名散列进行解密,得到原始散列值。然后从JAR文件的输入源计算得到的散列值相等。最后比较计算的散列值是否和原始散列值相等。如果相等,就说明公锁的所有者的确对该JAR文件进行了签名并担保,该JAR文件在此之后也没别人窜改。这个JAR文件中包含的代码就可以被放在一个不严格的沙箱,这个沙箱信任你的签名。图3-4 显示了验证JAR文件的数字签名的过程。
Java中的数字签名和数字证书 - hubingforever - 民主与科学
三、数字证书
   对于大多数开发者,用户并不认识他。如果程序运行当中有什么恶意行为,用户很难在茫茫人海中去找其开发者,并让它负责。用户根本无法信任不认识或不是很熟的开发者的程序。这时就需要一些担保机构。
   开发者让担保机构对其程序进行担保,担保机构向开发颁发担保机构给开发者颁发一个公钥/私钥对,其中担保机构用它自己的私钥对要颁发的公钥进行加密,把加密后的公钥和其他一些信息放在一个叫做数字证书的东西中。开发者用担保机构颁发的私钥对程序进行签名,然后把担保机构颁发的数字证书一同放在程序中。
    用户在得到程序时,通过程序中的数字证书确定其担保机构,并取得担保机构的公钥来解密数字证书中的开发者的,然后用开发者的钥进行数字签名验证。如果验证通过,就说明该担保机构对这个程序进行担保。用户虽然不认识程序的开发者,但是如果其程序有什么恶意行为,用户可以找到担保机构担保机构能找到其担保的开发者,并追究其责任,甚至可以和用户一起起诉开发者。当然担保机构本身至少还是有一定信誉度的。
    这样的话,用户可以相信该担保机构担保的程序了。程序的开发者必须对它的程序负责,所以他也不敢放一些恶意的代码在其程序中。
  评论这张
 
阅读(5318)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017