密码学笔记(上)——加密通讯
这篇文章我尽量讲的通俗易懂,以我自己的理解去解释密码学在网络通讯中的应用。
若有疏漏,恳请指正。
参考链接
一、基础知识
这部分涉及到一些数学原理,我也不懂。
你不需要去深究它的实现原理,只要了解它的性质。
加密算法分类
加密算法可以分为两种类型:
- 对称加密
- 非对称加密
1. 对称加密
对称加密就是加密和解密时使用同一个密钥。
很常见的一个应用就是在创建压缩文件时指定压缩密码:
在解压时,使用的是相同的密码打开:
2. 非对称加密
非对称加密是指加密和解密使用不同的密钥,这两个密钥分别叫做「公钥」、「私钥」。
公钥是可以公开给所有人的,而私钥需要自己保密的。
公钥加密的数据只能用私钥解密:
私钥“加密”的数据只能用公钥“解密”:
哈希算法
哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。
哈希算法最重要的特点就是:
- 相同的输入一定得到相同的输出;
- 不同的输入大概率得到不同的输出。
哈希算法通常用来校验文件完整性。注意,它并不算是加密算法。
来看一个具体点的例子:当我们去网站上下载文件的时候,有的网站会给出文件的哈希值。
例如:
- 系统镜像下载
- 下载Eclipse
这里的SHA-1也好,SHA-512也好,还有你也许听说过的MD5也好,都只是一种哈希算法。尽管算法不一样,但都是哈希算法,性质上是一样的。
以上面的SHA-1算法为例。一个SHA-1能够接受任意大小的文件,但生成的SHA-1值却始终只有160位。(160位二进制码。上面的24b59706d5eded392423936c82ba5a83596b50cc
是为了给人阅读而转成的十六进制码,可以看到正好是40位)
如果在下载的过程中,文件哪怕出现了一丢丢的变化,SHA-1也会变得很不一样(即上文说的“不同的输入大概率得到不同的输出”),使人察觉。
仔细一想的话你会发现,世界上可以有无限多个不同的文件,但哈希值却是有限的。
因此可以推测:
存在多个文件对应一个哈希值的情况,即产生了哈希值的“碰撞”(我们碰到这种情况的几率极小)。
哈希计算是不可逆的。
事实上确实如此,所以我们不能用哈希值反推出原来的数据,但可以用来检查原数据是否完整正确。
快速回顾
会顾一下,我们刚才说了些什么:
- 对称加密加密和解密时使用同一个密钥
- 非对称加密是指加密和解密使用不同的密钥
- 哈希算法可以用来校验文件完整性
二、故事开始
一天,二狗要向张蛋借钱,但是没空见面,所以就在网上给张蛋发消息:
然而,这些消息在网上都是明文传输的,因此,很有可能被别人拦截、窃听、篡改:
可以看到,三柱成功地偷走了50块钱,并且在二狗和张蛋发现并报警之前拖延了时间,逃之夭夭。这就是明文传输的缺点。
(实际上,完整的发送内容应该是from: 二狗;to:张蛋;内容:麻烦借……
这样的。from和to这俩我省略了,它们不参与后面的加密)
所以,接下来的目标,就是要让二狗和张蛋的通讯变得私密、安全,有以下要点:
- 不允许其它人知道通讯内容
- 不允许其它人篡改通讯内容
这个场景和我们平时上网肯定不太一样,但先跟着本文走,后期我们会再提。
我们目前就是实现一个满足以上要求的加密通讯,等实现以后再考虑性能开销等问题,做进一步考虑。
1. 第一回合
二狗和张蛋决定先见一面,使用一个对称密钥。把每次网上聊天的内容拿这个密钥加密后再发给对方。
假设他们选择了7f2d5381
作为密钥。
可以看到,三柱在中间截获了通讯的信息,但是由于是密文,看不懂,所以就不知道其内容。
如果脸滚键盘随意篡改,那么接收方也不能正确地解密,会视为无效数据。
其实,仅仅到这一步,一个加密链接就形成了,不用担心窃听,不用担心篡改,很安全。
但还是有一个很大的问题:
双方需要先见上一面,保证只有这两个人知道密钥
如果二狗和张蛋都很忙,没时间见面,那怎么办呢?
让我们看另一种方案,用非对称密钥实现加密通讯。
2. 第二回合
用非对称密钥实现加密通讯比较复杂,不要着急。
首先,既然是非对称密钥,那肯定要生成公钥和私钥对。
第①小步:二狗需要生成一对公钥,张蛋也需要生成公钥。
第②小步:二狗给张蛋打电话(或反过来)。
他们都听出了对方的声音,还互相问了几个问题。确认了电话那头是本人后,他们在电话中交换了自己的公钥。
现在,他们都有各自的私钥以及对方的公钥,已经完成了准备工作,接下来可以正式开始了。
第③小步:具体通讯过程。
首先,二狗要给张蛋发一个信息。
二狗会先把信息通过自己的私钥加密,然后把加密过的信息再用张蛋的公钥加密。当张蛋拿到数据时,会先用自己的私钥解密,然后用二狗的公钥解密,就能得到明文了。反之亦然。
那究竟为什么要这么做呢?
剖析
我们首先得假设最坏的情况:
我们知道,二狗和张蛋通过电话确认了对方的身份,交换了公钥。这时候,他们可以肯定对方收到了公钥,但电话有可能被窃听,所以有可能其它人也收到了公钥。
这时候,三柱拥有二狗和张蛋的公钥,但实际上我们接下来会看到,这一点用也没有。
首先,如果二狗要向张蛋发送一个信息,为了确保只有张蛋能收到,二狗会用张蛋的公钥加密。此时,即使三柱截获了这段信息,也没有办法解密,因为解密需要张蛋的私钥。也就是第一点:发给张蛋的消息只有张蛋能收到。
但是,三柱也有张蛋的公钥,他完全可以装作二狗来给张蛋发消息。所以,我们最开始要用二狗的私钥加密一次。这样,当张蛋解开外层密文后,会看到内层密文。这时候,张蛋会尝试用二狗的公钥解开,如果解开成功了,就能说明消息确实是二狗发的(因为其它人没有二狗的私钥),如果失败了,则说明可能有人冒充二狗,直接把数据丢弃就好。实现了第二点:张蛋可以确认消息来自二狗。
现在我们发现,尽管三柱有二狗和张蛋的公钥,但一点用也没有。外层的加密使三柱无法得知内容、无法篡改,内层的加密使三柱无法伪装。
如果张蛋要向二狗发消息,那么反过来就是了。
这样,就实现了使用非对称密钥的加密通讯。
最明显的优点就是公钥不用担心泄露,因此不用见面了。(实际上,公钥知道的人越多越好,不过这个讲到签名机制的时候再说)
三、 难度升级
刚刚我们已经使用非对称密钥实现加密通讯了。二狗和张蛋只要打个电话交换下公钥,以后就可以在互联网上加密通讯了。
但现在,难度升级:如果两个人根本不认识呢?就没办法确认一开始的公钥是对方的了,那要怎么实现加密通讯呢?
我们先脱离互联网,举一个现实一点的例子:
腾小讯和老干妈一开始根本就不认识,那腾小讯要怎么确认对方是老干妈,或者老干妈怎么确定对方是腾小讯?
很简单,找一个可信的第三方机构:警察、法院、工商局……
只要能证明腾小讯是腾小讯,老干妈是老干妈就行。
于是,双方就可以正式展开合作了。
这里的重点是有一个可信的第三方。
应用到网络上,也是一样的,只要有一个可信的第三方,就能确认对方的身份。
1. 三方各自生成自己的公钥密钥对
2.腾小讯和老干妈各自亲自去一趟工商局
去工商局的目的有两个:
- 获取工商局的公钥
- 要求工商局用工商局的私钥加密一下自己公司的一些信息和公钥
以腾讯方为例:
这时候,把加密后的内容——我们称之为“证书”(真实的证书还略有区别)发给老干妈。
(老干妈实际收到的内容应该是from:腾小讯;to:老干妈;工商局给的证书:YuaJpe……;
)
老干妈方亦是如此。
如果有人篡改了证书,那么用工商局的公钥尝试解密也会出错。
如果有人窃听,用工商局的公钥解开,得到的也只是腾小讯的身份和公钥,而公钥本来就是可以公开的。
还记得上一章的解决方案存在的问题吗?现在,不管是什么公司,老干妈、可口可乐、山西老陈醋、心相印……只要它们去一趟工商局,以后他们直接就能在网上进行加密通讯了。
实际上,这个“工商局”实际对应的就是证书颁发机构(Certificate Authority),简称CA。
四、非对等情况
上一章,我们实现了腾讯和老干妈的加密通讯。
很感谢你看完了,但接下来要说的,才是真正的、贴合现实的例子:
当我们访问百度的时候,可以看到它使用的协议是https,Chrome旁边还给它加了个小锁表示安全,点击一下就会告诉我们,连接是安全的:
但有些同学可能产生这样的疑问:不对啊,我没去过工商局,怎么就直接变成安全连接了?
我怎么知道对方是真的百度?
虽然你没有证书,但百度是有的嘛,百度把证书发给你就好了嘛。
但你真正想问的应该是:我又没去过工商局(代指实际中的CA),怎么拿到工商局的公钥呢?
工商局的公钥肯定不能通过网络拿到,否则就变成无限套娃了。实际上,所以,你的电脑中一开始就应该有工商局的公钥了。聪明的你一定想到了,这个“一开始”就是你装系统地时候,工商局的公钥就存在你的操作系统里。
问:那如果我的操作系统就是有问题的呢?
答:如果微软是假的,如果工商局是假的,如果政府是假的……老兄,你怎么确定你不是生活在楚门的世界里呢?无论怎样,你总要相信什么吧。先有一个可靠的地基,我才能为你搭建高楼大厦。
百度怎么知道我是谁?
实际上,百度不知道,它也不需要知道,因为搜索功能本来就是开放的。
它更关心的是,怎么保证这个通讯过程是加密的,防止你的搜索记录被别人看到。
而有些功能,例如百度网盘,使用这些功能是要认证的。但也不是通过证书认证的方式,而是通过登录的方式,只要保证你的用户名密码不被看到就好了:
操作步骤
实际上,步骤很简单:
- 你可以给自己起个任意的名字(甚至在这次通讯完以后就可以丢弃),比如
eghew-9r3e8fgw-erirgd8shf8-eqfhe9fhefe
,发给百度就好:from:eghew-9r3e8fgw-erirgd8shf8-eqfhe9fhefe;to:百度;我的公钥:3ht92tj4392th1r……
- 百度把证书发回给你,你验证一下,拿到百度的公钥。
有了对方的公钥就又可以实现安全通信了。
让我们稍作分析:
- 第2个步骤没问题,证书和里面的公钥本来就是随便给的。那第一个步骤有问题吗?
- 如果黑客说自己是
eghew-9r3e8fgw-erirgd8shf8-eqfhe9fhefe
,给百度发信息。那么百度会直接把他拒绝掉,因为已经有一个对应的公钥了。如果黑客在你之前给百度发信息,那么反过来,黑客可以连上,但你会被拒绝掉,但,这,有什么意义呢?黑客没有你的账号密码无法登录,自然看不到敏感信息。而你完全可以再生成一个临时名字啊,再来一遍啊。
所以,我们实现了非对等情况下的安全通讯。
和上一章的主要区别就是我们是个Nobody,和百度的关系不对等而已。
未完待续
一开始,我本来想用一篇文章讲完加密通讯的所有内容。但写这篇文章所花的时间比我想的多不少,因此临时决定分多篇来讲述。
细心的同学应该会发现我在基础知识里提了哈希算法,但后期根本没用到。而且我所讲的知识和实际中的网络通讯也有不少区别。
确实如此,比如:
- 如果你不需要防窃听,只要防篡改,可以使用哈希算法来减少加解密的计算量(数字签名)
- 如果你用公钥密钥体系建立了安全连接,那么以后就可以使用对称密钥来减少计算量
- 证书的内容其实远不止身份和公钥,还会包含更多信息
- 证书颁发机构也存在一定的管理机制,就比如证书签发机构也会分层
- ……
这些我并非不知道,而是有意地略过甚至不提。
因为一开始就说过,我们的目标是一个私密、安全的通信,我希望能用尽量少的知识(对称密钥+非对称密钥)去实现这个功能,尽量减少新概念的引入。当实现这个目标后,再考虑优化。
对于优化的介绍,应该是下篇文章的事了
感谢您的阅读
如有疏漏,恳请指正