文章更新于:2020-04-02
注:本文参考自机械工业出版社《密码工程原理与应用》。
密码学是一门关于加密的艺术和科学。
密码学是整个安全系统的一部分,但也是最关键的一部分。
密码学通常提供系统的访问控制功能。
每个安全系统的安全性都取决于它最脆弱的部分。
为了提高系统的安全性,我们需要提高系统最脆弱地方的安全性。所以我们必须先知道那些是最脆弱的。这可以用一个分层的树结构来完成,系统的每部分都是有哪些环节,同时每个环节还有哪些子环节。我们可以将这些环节组织成一颗攻击树(attack tree)
。
因为如果有攻击者想要攻击系统,它一定会攻击系统最薄弱的环节。
所以我们必须把对手设定为最狡猾
的对手,这样我们才能更好的完善我们系统的安全性!
注1:密码学传统上为了方便举例称发送方为 Alice
,接收方为 Bob
,窃听者为 Eve
。
注2:如果你查字典,你会发现密钥读(yue)。但是一些密码学的老教授读的时候会读 (yao)。所以在不致产生歧义(密钥(yue)和蜜月同音~))的时候,你读哪种应该都是可以的。
为了不让我们发送的信息被窃听,我们可以选择在发送信息前,将明文 m
通过加密函数 E
用密钥 ke 进行加密成密文 c
,然后再发送。
接收方受到密文 c
以后通过解密函数 D
用密钥 ke 进行解密为明文 m
,至此,信息发送完成。
如果 Eve
进行了窃听,那么他只能得到密文,没有密钥 ke 它将无法得到明文。
那么问题来了,如何传送密钥吗?如果有安全的信道用来传送密钥,那么直接用来发送信息好了?
这涉及到了密钥的分发问题,这里先不拓展。暂且认为 Alice
和 Bob
使用了另外一个安全的信道进行密钥的协商。比如上次见面的时候协商,或写在纸上邮寄过去等。
kerckhoff
原则
加密方案的安全性必须仅仅依赖于对于密钥 ke 的保密,而不依赖于对于算法的保密。
事实证明,不公开的算法往往是存在问题的,是经不起检验的。
在上一章节中,我们解释了如何进行加密以防止 Eve
窃听到明文。但是这却防不住 Eve
对信息进行修改。
因为 Eve
既然可以窃听到信道,那么他相应的也有可能对信息进行修改、拦截删掉、或者改变几个信息的顺序,这些都是可能的。
而接收方却无法分辨信息是否被篡改。为了解决这个问题,我们引入了认证
的概念。
和加密一样,认证也需要使用一个密钥,这里记为 ka
在发送信息之前,我们先使用 ka 对信息进行计算得到一个消息认证码(Message Authentication Code),也可以称为 MAC
。
发送信息的时候,连 MAC
也一起发送过去。
Bob
接收到信息m
和 MAC
以后,自己对信息计算一遍 MAC
,看是否与发过来的 MAC
相同。如果相同,说明信息安然无恙。如果不相同,就说明信息被篡改或已损坏,直接丢弃便是。
现在如果 Eve
进行窃听即便同时篡改了信息,但因为他没有认证密钥 ka ,所以他的篡改是无法起到作用的,因为 Bob
收到发现 MAC
不对就该扔了不是~
但是这还有一个问题,就是这还不足以抵挡 消息重放攻击
。 什么是消息重放攻击呢?
就比如说,Eve
窃听到信息并不篡改,而是连同 MAC
保存下来,等待一段时间以后,再连同 MAC
一起发送给 Bob
,由于 MAC
是有效的,所以 Bob
会认为消息有效。
如果在某些场景信息的顺序很重要的话,这同样会造成危害。为了避免这种情况,我们可以在消息中加上编号。并在接收的时候验证编号,如果受到的编号小于已经收到的信息编号,便丢弃。说白了就是如果收到 2 号信息以后,才收到 1 号信息,1 号信息就会被丢弃。
注:加密
和 认证
是两个不同的概念。加密只能保证不泄露明文,而认证则是保证消息的完整性。
在上述我们讨论的加密方案中,两者发送信息需要有一个加密密钥 ke 。我们可以设想一下,如果一个团队人数比较多的话,交换密钥是一个非常麻烦的事情,而且人一多,密钥的数量也显著增多。
你的老板可不希望你把大量的工作时间话花费在交换密钥上。
为了解决这个问题,我们引入 公钥加密
的概念。
首先我们使用一种特殊的算法生成一对密钥(SBob ,PBob),其中 SBob 为私钥,PBob 为公钥。
然后 Bob
公开他的公钥!这样一来,所有人都可以获取 Bob 的公钥,这也符合公钥的名字哈。
接着 Alice
就可以使用 Bob
的公钥对信息 m
进行加密成密文 c
,然后发送给 Bob
。
Bob
受到密文 c
以后,使用 私钥 SBob 对密文进行解密得到明文 m
。
那么 Bob
想给 Alice
发信息是用自己的私钥进行加密吗?不可能的,那样任何拥有 Bob
公钥的人都将可以解密信息。那用什么加密?给 Alice
发信息当然是用 Alice
的公钥啦!
所以说,给谁发信息就用谁的公钥加密,而解密信息则只有对应的私钥才可以。那么如果你想让人家给你发信息,你公开自己的公钥就可以了。
注1:公钥和私钥是不一样的,不像之前提到的加密密钥 ke 。在公钥加密系统中,甚至连加密函数和解密函数都是不一样的。
注2:没有私钥你想解密公钥加密的信息?你解密个试试,我看着你解密。
前文我们提到了消息认证码的概念,其实数字签名可以理解为使用公钥加密技术实现的消息认证码。
假设 Alice 想要发送消息给 Bob:
1、Alice
先校验出要发送信息的 Hash
,然后 使用私钥对 Hash
进行加密得到加密结果 s
。
2、Alice
将消息和加密结果 s
一同发送给 Bob
。
3、Bob
收到以后使用 Alice
的公钥对加密结果 s
进行解密,得到由 Alice
发送的 Hash
。
4、Bob
自己计算一遍 Hash
然后对比,进行验证。
使用公钥加密的数字签名虽然保证了消息的加密,但却无法保证使用但是正确的公钥,可能公钥已经被掉包了却浑然不知。
PKI 的中心思想是设立一个中心机构,称为证书机构或CA。每个用户都把他的公钥报给CA并向CA证明自己,然后CA使用数字签名签署用户的公钥。
之后,每个人都只需要有CA的公钥即可验证对方是否是正确的要通信的人。
只有密文,试图将其解密成明文。难度最大。
同时知道明文和密文,试图得到解密密钥。
比已知明文攻击更强大。
可以构造指定明文的密文,试图得到解密密钥。
比选择明文攻击更强大。
可以构造指定明文的密文,也可以得到指定密文的明文,试图得到解密密钥。
此攻击得名于生日悖论。
如果一个房间里由23个人,那么其中两个人生日相同的概率超过50%。
一般来说,如果一个元素可以取N种不同的值,那么随机选择了大约 N \sqrt N N 个元素之后,就可以预期出现第一次碰撞。
很多情况下,我们讨论 n 位的值,因为有 2n 个可能的值,所以集合中需要有 2 n \sqrt {2^n} 2n = 2n/2 个元素才能预期出现第一次碰撞。我们将经常谈到 2n/2 这个届,或称为生日届。
中间相遇攻击与生日攻击同属于碰撞攻击。
在生日攻击中,我们期待同一个值在相同的元素集合中出现两次,即出现碰撞。
而在中间相遇攻击中,我们则自己构建一个集合,并等待这两个集合出现交际,即出现碰撞。
有后续…