什么是数字签名
到目前为止,我们看的大多是怎样不让别人读到。可有时候消息不需要保密,只想确认它真是那个人发来的。上一课也留下了一道作业:要确认密钥交换的对方是真的。要是发信人能用只有自己才有的私钥,在消息上留下一个像印章一样的记号,而谁都能用他的公钥确认这个记号的真假,会怎样?这就是数字签名。
不知道是谁发来的
假设来了一封信,末尾写着某个人的名字。真是那个人写的吗?名字谁都能照着抄,内容也可能在路上被人悄悄改过。光看文字,没法知道。手写的签名还能比对笔迹,可电子邮件里打出来的名字,谁打都一模一样。
这和保不保密无关,内容全都公开也没关系。我们想知道的,只是它是不是真的出自那个人,路上有没有被改过。
点“怀疑名字”和“怀疑内容”两个按钮。名字是不是抄来的、内容有没有被改,光看文字分辨不出来。
亲手点过就知道,很憋屈:就算写着名字,也拿不准。我们需要两样证据:一是真的出自那个人,二是路上没被改过。
要是有一个记号,能同时证明这两点,又没人能模仿,那就好了。公钥那一课里的那对钥匙,正好能做到。
用私钥签名
公钥那一课里,是用收件人的公钥上锁。签名方向正好相反:发信人用自己的私钥给消息附上签名。这不是用挂锁锁上,更像在消息旁边盖一个章,所以内容照样全看得见。
实际上,签名不是针对整条消息,而是用私钥对消息的哈希,也就是它的指纹做运算得出的。私钥只有那个人有,所以这个章只有他盖得出来。
点“用私钥签名”。内容照样看得见,还附上了只有那个人才做得出的签名。
签名附上了,消息的字却一个也没被遮住,因为这不是上锁,而是加了一个章。这个签名来自消息内容的指纹,所以和内容紧紧绑在一起。之所以对指纹而不是整条消息签名,是因为指纹又短、长度又固定,再大的文件也能很快签完。内容一变,指纹就跟着变,所以只给指纹签名,就足以守住整条消息。
而且要做出这个章,必须有那个人的私钥。私钥从不离开主人的手,所以别人做不出同样的章。那么,收件方怎样确认它?
用公钥验证
收件人用发信人的公钥来验证签名。验证就是追问:这个章真的是用和这把公钥配对的私钥盖的吗?它和现在收到的内容的指纹对得上吗?
两样都对得上,验证就通过。用别人的私钥盖的章,拿这把公钥一验就失败,因为只有公钥和私钥配成一对,才能通过。
把签名一个个点开,用民宇的公钥来验证。只有用民宇的私钥盖的签名能通过,用别人的钥匙盖的都会失败。
只有用配对私钥盖的签名通过了。通过的意思很清楚:这条消息真的是那个人发的。公钥全世界都拿着也无妨,因为公钥只能验证,做不出签名。就像公司把印章的样子公开给所有人比对,但印章本身锁在保险柜里,只有一个人能拿出来用。
盖章的权力只属于私钥的主人,查章这件事却对所有人敞开。这正好是用公钥上锁的镜像。
是真的,也没被改过
签名和内容绑在一起,所以验证一通过,就同时证明了两件事:一是真实性,真是那个人发来的;二是完整性,一个字都没改过。
路上有人哪怕只改动一点内容,指纹也会完全变样,跟绑在一起的签名就对不上,验证立刻破裂。改动的那一个字,就成了警报。
点“改一下时间”。哪怕只改一个数字,内容也和签名对不上,验证就破裂了。
只改了一个字,验证马上就失败了。收件人看到这个失败,就知道这不是原来的内容,能停下来,不轻信。另外,用私钥签了名的人,日后也没法抵赖说不是自己发的,这叫不可否认性。
所以数字签名广泛用在软件更新、电子合同、公文这些讲究来源和原件的地方。现在把上锁和签名并排放在一起,整理一下。
小结
归纳起来是这样:数字签名把公钥加密的那对钥匙倒过来用。发信人用自己的私钥给消息的指纹签名,收件人用发信人的公钥来验证。验证通过,就同时证明了消息真是那个人发的,而且路上没被改过。
上锁是为了让内容保密,签名是为了证明是谁发的、有没有被改过。
点“上锁”和“签名”对比一下。上锁守住秘密,签名证明真实性和完整性。
现在你知道了上锁和签名的区别:用收件人的公钥上锁,秘密就守住了;用发信人的私钥签名,真实性和完整性就得到证明。同一对钥匙,只要换个方向,就能做两种事。
不过,验证要有意义,还有一个前提:那把公钥必须真是那个人的。凭什么相信一把公钥,下一课讲证书。