2011年9月6日星期二

gnupg密钥签署原理和过程

    gnupg的密钥基础运用比较简单,有能力跑过来看我blog的应该都比较清楚了。不过最近接触了gnupg密钥的一些复杂运用,才发现——这玩意,居然能构造类似于PKI的复杂密码体系呢。
    gnupg的密码体系和PKI类似,又有区别。PKI密码体系有数个根节点,负责验证服务。然而gnupg没有这种根节点,一切都是以社会关系网络运作的。更加复杂,也更加接近自然社会体系。
    首先是gnupg的基本密码原理,公钥和私钥对。利用私钥签署,公钥验证。公钥加密,私钥解密。这是最基础的两种用法,我们略过不谈。密钥签署的问题提出来源于,我如何相信我得到的密钥,真的来自他所声称的这个人?
    例如,我得到了来自Linus Benedict Torvalds的一封邮件,上面说blahblah。当然,听起来应当高兴,不过暂缓,这个信真的是linus本人写的么?这时候,我可以导入linus的公钥,验证签名——当然,如果有签名的话。不过问题又来了,你如何保证得到的是linus本人的公钥,而不是某个试图破坏系统的人伪造的呢?
    好吧,为了解决这个问题,gnupg设计了互相签署机制。当我签署了某个人的公钥,并且将我的签署上传到公钥服务器(或者发送回给本人)的时候,我就为这个人的真实性做出了背书。例如,当我为thomas做了公钥签署,然后上传到了公钥服务器。然后thomas向某个他并不直接认识的我的朋友发送了一封邮件——例如发送给了julia。julia收到信的时候,会从服务器上下载thomas的公钥,然后看到我的背书。如果julia相信(trust)我,那么gnupg就会自动完成验证。当然,将公钥上传到服务器会略微降低安全性,所以如果限于安全考虑,我没有上传到公钥服务器,而是传回给本人。那么thomas就必须在给julia发送邮件的时候,附上公钥。julia一样能看到公钥上我的签名。
    下面是如何操作。
    首先你必须获得公钥,以下是从公钥服务器上下载的方法。
gpg --keyserver <keyserver> --recv-keys <Key_ID>
    而后,你需要看到这个公钥的fingerprint。
gpg --fingerprint <Key_ID>
    再然后,就是比较困难的部分。你需要和这个公钥的拥有者碰头,找个地方喝个咖啡,或者一起出来玩什么的。然后,查看他的有效证件,和本人对照,并且取得他本人认可的fingerprint。
    这点非常重要,不要轻易的使用线上fingerprint交换来替代这个过程,也不要随意的为别人进行签署。你必须*确定*你签署了本人的密钥,线上获得的key,是完全可能被修改的,这是对所有信任你的人的负责。
    再然后,就是简单的签署。
gpg --default-key <Key_to_use> --sign-key <Key_ID>
    最后,上传公钥,或者传回给本人。以下例子是上传到服务器的,不过记得先征求对方同意——除非你原本也是从服务器上取得的公钥。
gpg --keyserver <keyserver> --send-key <Key_ID>
    至于revoke什么的,暂且就不说了。
    其中最麻烦的,就是上述过程中,两个人碰头的部分。为了简化这个部分,gnupg使用者经常有种gnupg keysigning party[2]的聚会,互相交换和签署密钥。

reference:
[1]. The GNU Privacy Handbook http://www.gnupg.org/gph/en/manual.html

没有评论: