GnuPG 签名
本文介绍 GPG 签名
学过 RSA 算法之后,对于使用两个密钥非对称加密的这种加密方式已经比较熟悉了。但是从数学上讲,除了使用公钥加密可以用私钥解密之外,反过来用私钥加密也可以用公钥解密。所以这就产生了公私密钥对除了加解密之外的另一个用途:签名和验证。
假设现在张三生成了一对公私密钥,私钥自己留着,公钥公布出去。加解密的过程就是,李四拿到张三的公钥把信息加密,发给张三,张三再把信息用自己的私钥解密,就看到内容了。但现在如果张三想对外公布一个信息,他不需要加密这个信息,但是想对外证明,这个信息的确是他公布的,怎么办呢?
因为张三的私钥只有张三有,所以张三可以用这个私钥加密自己的信息,然后把这个加密后的信息跟自己要公布的明文信息一起发出去,这样其他人一方面可以看到张三公布的明文信息,另一方面也可以拿张三的公钥尝试解密一下随明文信息附带的加密信息,如果能解开,且解密后的信息与明文一致,那就说明这个信息的确是张三公布的,且公布之后没有被人窜改。
实际的签名和验证过程是不是这样我不清楚,但这应该就是原理了。
我们现在把这两个过程结合起来,假设李四也有一对公私密钥,私钥自己留着,公钥公布出去。李四想给张三发信息,他可以用张三的公钥加密这个信息,但仅仅如此的话,张三收到了这个信息之后,并不知道这个信息是谁发送的,毕竟张三的公钥是公开的,谁都可以拿到然后给他发信息。即便信息里落款是李四,但这也不能完全确保这个信息就是李四发送的,毕竟谁都可以冒李四的名。这时候的问题其实就是,李四在向张三发送这个信息的同时,还想证明这个信息的确是李四发送的,怎么办呢?就是签名。
首先,李四先用张三的公钥加密自己要发送的信息,得到“密文”,然后再用自己的私钥加密这个密文,得到“签名”,然后李四把密文和签名同时发送给张三。张三拿到密文和签名之后,可以用李四的公钥解密签名,得到的内容如果与密文一致,就说明这个密文是李四发送的,且发送之后没有经过窜改,然后张三再用自己的私钥解密这个密文,就能看到李四给他发的信息了。
实际的签名和加密,以及验证和解密的过程可能并不是这样,但这大概就是原理吧。
以上过程建立的其中一个基础,就是李四确定外面公开的这个所谓的张三的公钥,的确是张三的公钥,而张三也能确定外面公开的这个李四的公钥,的确是李四的公钥。但是谁知道呢?就如同任何人都可以冒李四的名一样,任何人也都可以冒李四的公钥。所以如果你看到李四发布了一个公钥,声称这个是他的公钥,你该如何确认这件事呢?或者说,你该如何认证李四的公钥,的确是李四的公钥呢?
其中一个简单的办法,就是去找李四问问。当面得到亲口承认之后,你就可以认证这个公钥,的确是李四的公钥了。
但是这个简单的办法,大部分时候都不是那么实用,你不可能去跟每个人确认这个公钥是不是他的公钥。有的人可能远在大洋的彼岸,而且与你素不相识,你没办法去跟他们当面确认的。那怎么办呢?
假设现在有一个中间人,王五,他也有一对公私密钥。因为某些原因,你完全信任王五,且能确定你拿到的王五的公钥的确是王五的公钥。这是前提。然后王五通过某些途径,也确定了李四的公钥就是李四的公钥,这时候你就可以因为王五的缘故,而信任李四的公钥。
具体的操作过程可以如下:
在张三的电脑上,张三生成了一对自己的公私密钥 A,张三完全信任密钥 A,因为这是他自己创建的。而后张三从网上收到了王五的公钥 C,通过某些途径(当面确认或者其他方式)认证了公钥 C 的确是王五的公钥,然后张三就用自己的私钥 A 给公钥 C 签名了,这时候在张三的密钥管理软件里,公钥 C 就会被认为是可信任的公钥,因为它被有绝对信任等级的私钥 A 签名了。
之后张三又从网上拿到了所谓的李四的公钥 B,但是因为某些原因,张三无法直接确认这个公钥 B 是不是李四的公钥。然后张三发现公钥 B 被私钥 C 签名了,张三通过用公钥 C 验证后发现没有任何错误。因为张三信任密钥 C,所以张三就可以认为,这个公钥 B 也没有问题,就是李四的公钥。在张三的密钥管理软件里,因为公钥 B 被私钥 C 签名,而公钥 C 被私钥 A 签名,而张三绝对信任密钥 A,所以张三也可以信任公钥 B。
其实上述认证过程有一个问题,虽然张三可以通过一些方式确定公钥 C 是王五的公钥,但是被私钥 C 签名的公钥 B 并不是张三亲自认证的,而是由王五认证的,张三有多少程度可以相信王五一定是认证准确的呢?其实不好说,所以这里就有一个密钥信任等级。当然这个信任等级由张三自行标记。如果张三对公钥 C 标记为完全信任,那被私钥 C 签名的公钥 B 也是可以信任的;如果张三对公钥 C 标记为不信任,那公钥 B 也就变得不可信任。
差不多就是这样。