代码签名和认证

xiaoxiao2024-05-07  30

要对一段代码作担保或者签名,必须首先生成一个公钥/私钥对。用户应该保管那把私钥,而把公钥公开。一旦有了拥有了一个公钥/私钥对,就必须将要签名的class文件和其他文件放到了一个JAR文件中,然后使用一个工具对整个JAR文件签名。这个签名工具将首先对JAR文件的内容进行单项散列计算,以产生一个散列。然后这个工具将用私钥对这个散列进行签名,并且将经过签名后的散列加到JAR文件的末尾。这个签名后的散列代表了你对这个JAR文件内容的数字签名。当你发布这个包含签名散列的JAR文件时,那些持有你的公钥的人将对JAR文件验证两件事:这个JAR文件确实是你签名的,并且在你签名后这个JAR文件没有做过任何改动。散列也称消息摘要,它是通过单项散列算法产生的。

要认证一个已签名的JAR文件,接受者必须用公钥对签名散列进行解密,得到的结果应该和从JAR文件计算而得到的散列值相等。为了验证一个JAR文件在签名后未被动过,接受者只要对JAR文件的内容实施单项散列算法,就像在签名过程中所做的那样。(记住,并没有对JAR文件的内容进行加密,所以任何人都可以看见它。你只是将一个数字签名驾到了那个JAR我呢间中。)如果得到的散列值和加密的散列值匹配,那么接受者就可以推断,你确实为JAR文件进行了担保,而且这个JAR文件的内容在加上你的签名以后没有被改动过。这个JAR文件中包含的代码就可以放在一个不严格的沙箱中。

签名和认证如下图所示:

 

 

这种方式就像这样:你为某个公司介绍一个人,而那个公司不知道是好人还是坏人(就是说不知道是安全代码还是恶意代码),你怎么办呢?你就给那个公司寄了一个箱子,箱子里面装的是那个人的指纹(就是用私钥对散列值加密),而箱子是被一把锁(就是你的私钥)封闭了的,而这个人到了那个公司之后,那个公司首先用你给他的公钥(就是那个把锁的钥匙)解开那个箱子,然后取出箱子里的指纹(就是用公钥将签名值进行解密后的散列值),如果这个指纹跟那个人的指纹(就是原class文件的散列值)相符,那么这个公司就可以确定这个人是你推荐来的,你为这个人担保了的,所以这个人是个好人(意思就是安全的代码)!如果不相符,那么就拒绝这个人(恶意代码)!整个过程这个箱子是封闭了的,而且只有这个公司才能打开这个箱子查看指纹。但是这种方式不是绝对安全的,试想一下,我是一个黑客,我可以从三方面下手,第一,我的恶意代码产生和安全代码相同的散列值,这种方式不切实际,因为这就像破解密码一样。第二,盗取你的私钥,如果我得到你的私钥,那么我为自己恶意代码签名,就可以为所欲为,但是这种方法就像盗取别人的密码一样。第三,将别人的公钥替换成自己的公钥,这种方式很容易做到,如果某个人的公钥是从网上发布的,那么别人在下载这个公钥之前我把它替换成自己的公钥,这样的话,我再用自己的私钥为自己的恶意代码签名(私钥和公钥是成对的),那么下载公钥的人却误认为是解密后的散列值与原始class散列值相同(其实他只是用我的公钥解密我的私钥而已,所以我编写什么代码也可以蒙混过关),我就利用了用户对别人的信任来侵入他们的系统了。

所以从上面就可以看出,公钥发布成了一个问题,其实公钥发布的困难本身也是一个认证问题。试想一下,“我怎么确认这个代码是不是恶意代码”和“我怎么确认这个公钥是不是假公钥”属于同样的问题,基于这种思考,建立了许过证书机构来为这些公钥做担保。例如,你可以到一个证书机构去,给出你的信任证明(例如出生证明、驾驶证、护照等等)以及你的公钥。一旦确认你是真的如你自己所说的那个人,证书机构将会用证书机构的私钥对你的公钥进行前面,最终得到的数字序列被称为证书。这样,你就可以发布你的证书了,而不是你的公钥了。这种方式只是相对好了些,因为要替换公钥的话必须还要得到证书机构的私钥。

参考书籍:《Inside the Java Virtual Machine,Second Edition》

相关资源:Android签名验证代码
转载请注明原文地址: https://www.6miu.com/read-5015214.html

最新回复(0)