偷偷摸摸看了阮一峰的数字签名是什么?,评论也都很精彩。小弟也来凑凑热闹,蹭蹭热度。说一下自己的理解,各位尽情可喷。
心中纵有千般疑问,也只能埋在心里。(搞不定数学啊!这里不谈数学,数学太他么难了。)
我觉得要一个一个问题来说。
私钥与公钥
这个我也不懂,我又不懂数学,我只会用程序生成。不过不要紧,只需记得它俩天生一对就行了。啥意思?假设有 【私钥A、公钥A】 和 【私钥B、公钥B】,还有一个字节串(文本文件,二进制文件都是字节串),如果我用 私钥A 加密一下,那么就只能用 公钥A 解密;用 公钥A 加密一下,也只能用 私钥A 解密。不关B什么鸟事。也不知道RSA钥匙空间是个啥情况?我就假设 钥匙对 的唯一性,只有配对才能互解;而这也是为啥可以加密,为啥可以签名的基石。
这里,还有几点说下。
- 什么叫加密,解密?
加密就是换了一个形式,解密就是还原。举个栗子,伪代码,RSA_encrypt(bytes, 私钥A) ==> bytes', RSA_decrypt(bytes', 公钥A) ==> bytes
。注意,这里加密解密都是用 RSA 相关函数。特别注意 RSA_decrypt(bytes', 公钥B)
会出错(据说是满足不了一个数学条件)。还有,某些人会用 XXX_decrypt(bytes', 钥匙C) ==> bytes''
这个嘛,大哥,我们用的是 RSA,你这个 bytes''
还不如我手动打开 bytes'
在后面添加字节 xxoo
,就好像是 decrypt(byptes', 'xxoo') ==> bytes'''
,我这是手动解密啊,哈哈。不知道说清楚没有?就是说我用RSA的算法加密了一个文件,你却用凯撒算法“解密”了一个新文件,说:“我解密了”。字节串变换字节串嘛。我上去就是一脚。
- 公私有何区别?
私钥与公钥作为天造地设的一对,互相可解。看起来没啥区别啊!假如有一钥匙对,一个拿给你,一个拿给我。你加密,我就能解密;我加密,你也能解密。这不是公私不分嘛!其实这个钥匙对中,公私是分明的,你可以自己生成一对,打开看看它们的文本表示,私钥长得多,还可对私钥设置口令。有一个细节是,私钥与公钥加密、解密所用的函数都是不同的,大概 RSA_public_encrypt, RSA_private_decrypt; RSA_private_encrypt, RSA_public_decrypt
(上一条的伪代码还是有些瑕疵。)所以,你要是把 私钥 当 公钥 分发出去,自己却留着 公钥 当 私钥,那么就会错误百出。只是,仅仅谈 加解密 这点,公私作用是一样的。
- 丢了怎么办?
私钥丢失,比如说你唯一的电脑被儿子弄坏,修不好。恭喜你,你肯定有老婆了。只好重新生成秘钥对了。谁要是用你以前的公钥给你发密信,告诉他用新的公钥即可。
上面扯了这么久,下面我们来谈正事。
原本打算搞几张图片,活跃一下气氛,表达更形象。不会弄。算了。写到这,才发现,这个话题太大了,我根本驾驭不了。只能简化了。
加密,我要给老王的老婆发消息,怕别人知道,就用老王的老婆的公钥加密一下,别人拿到也没用,老王的老婆拿到后,用她自己的私钥解密就行了。由此,可以看到,我想发密信给谁,用他的公钥加密后,再发,就比较放心了。
签名,我先用老王的老婆的公钥把消息加密,然后我再用我的私钥加密一次。其他人拿到后,只能用我的公钥解开,大家一看,“哦,这是小李发出来的”,但是看不到我的原文;老王的老婆用我的公钥解密了,心里乐开了花,的确是小李发的,然后用她的私钥再解一次,就能看到内容了。或者,我先用我的私钥加密一次,再用老王的老婆的公钥加密一次,发出去。别人打不开,老王的老婆用私钥解密,再用我的公钥解密,“哦,是小李发来的”。在这里,我的私钥作用就是签名,确实是我(即使不是我,也是我的那个私钥)发出来的消息。实际不是这么用的,一般都是签在摘要上面。
完整性,这里也提一提,毕竟还是容易混淆。想象这样一个场景,我发了 [str, hash(str)],你收到了,然后自己对str进行了hash,发现没错,那么str就是完整的;即使哪个2B截获了,改成[str’, hash(str’)],再发给你,你收到了,然后自己对str’进行了hash,还是没错,那么str’就是完整的。哈哈,这就是完整性。但是,情况不是这样的,坏就坏在,我像个傻逼一样,不该把 hash值发给你。我就发个 str给你,你算完hash,打电话(假定电话安全)和我核对一下。这里你可能要问,为啥不加密?因为我仅仅想说一下完整性这个概念,不想谈及安全。就比如,你昨天写了点字符串,你就可以算一个hash值,记在纸上;今天你想看看是不是完整的,有没有被改动,就再对它hash一下,和昨天的纸上记载的对比一下。当在网络上传输的时候,情况就开始复杂了。完整性本来是需要保存正本,然后副本来和正本一一对比;不过那样代价太大了,而hash,比如sha1提供了足够的可靠性,并且效率高啊,所以就用hash值来比较。
可以完全不提人,就画很多的钥匙对,概念可能更准确。但是实际钥匙都是个人或者机构持有的,所以就说成了谁的私钥,谁的公钥。比如 私钥小明 和 公钥小明 是一对的,如果某天 私钥小明 落入到了 大锤 手里,大家可能还不知道。 钥匙确实是配对的,但所属变了。对于签名来说,用 公钥小明,解开的一定是 私钥小明,我们就认为这个是消息是小明的,没想到却是大锤发的。严谨来说,我们可以说这个消息是 私钥小明 持有者发的。不客气的说,公钥小明 解开的,就是 私钥小明 签名的。具体谁人做的,无法保证,但一般就认为是小明,不排除小明给她老婆共享了 私钥小明。
上面简介了三个概念,不过都很理想;当进入到现实的时候,很多问题就要考虑了。首要考虑安全,安全第一嘛!私钥的安全就要靠你自己了。别人要是把刀驾到你的脖子上,那也保不住了。我们只考虑公钥的安全。
理想与现实
我们也只考虑网络传输(你驱车万里送一个文件,或者通过安全电话一个字节一个字节口读1G的文件给对方,也当我啥也没说)。
我们假设老王是不敢威胁他老婆的,她老婆的私钥是安全的,只有她自己持有。也就是假设每个人的私钥是安全的(如果你被控制人身自由,电脑被控制,身不由己,就当我啥也没说,你也别往下看了;凡事都要满足一定的条件才能成立)。
(TMD,编不下去了)
你拿到了C的公钥,那就一定是C的公钥吗?