我们在使用互联网交换数据时,数据需要经过各种各样的网络设备才能到达通信双方,如果数据在传输的过程中经过某些恶意用户的设备,就有可能导致信息被窃取。所以如果想安全的使用互联网,了解必须的安全技术是不可或缺的。

安全问题

我们首先了解一下在通信的过程中会遇到什么样的安全问题。

窃听

$A$ 向 $B$ 发送的信息可能会在传输的过程中被 $X$ 偷看,这就是窃听。

假冒

$A$ 以为给 $B$ 发送了消息,但是 $B$ 有可能是 $X$ 冒充的;同样 $B$ 以为收到了 $A$ 的消息,但是 $A$ 也有可能是 $X$ 冒充的,这种问题叫做假冒。

篡改

$B$ 确实收到了 $A$ 发送的信息,但是内容已经被 $X$ 给改变了,这种行为叫做篡改。

事后否认

$B$ 从 $A$ 那里收到了消息,但是 $A$ 在事后宣称消息不是它发的,这会导致互联网上的商业交易或合同无法成立,这种行为叫做事后否认。

在这篇文章中就着重解决这四类问题,对于窃听,我们对消息进行加密技术;对于假冒,我们使用消息认证码或数字签名;对于篡改,我们同样可以使用消息认证码或数字签名;对于事后否认,我们可以使用数字签名。

问题 解决办法
窃听 加密
假冒 消息认证码或数字签名
篡改 消息认证码或数字签名
事后否认 数字签名

数字签名存在无法确认公开密钥制作者的问题,我们可以使用数字证书来解决,具体的过程我们在后面分析。

对称加密

如果我们在互联网上直接将消息发送过去的话,有可能会被窃听,所以我们需要将消息变为密文,然后发送出去,将消息变为密文的过程叫做加密,同样在接收方需要将密文变为明文(消息),这个过程叫做解密。

在加密和解密的过程中需要用到密钥,所谓的密钥可以类比于钥匙,钥匙的作用就是加锁与开锁,而密钥的作用是加密与解密。根据加密和解密是否使用的是相同的密钥,可以分为对称加密与非对称加密:

  • 对称加密:加密和解密的密钥是同一个密钥
  • 非对称加密:加密和解密的密钥不相同

在本小节中就介绍对称加密,以及对称加密存在什么问题。

对称加密的过如下:

  1. $A$ 将密钥 $key$ 发送给 $B$
  2. $A$ 使用密钥 $key$ 对消息 $aaa$ 加密,得到密文 $xyz$
  3. $B$ 接到密文 $xyz$,使用密钥 $key$ 对密文解密得到 $aaa$

这时如果窃听者来窃听的话,因为窃听者没有密钥,所以无法得知明文是什么。

但是上述的加密有一个问题,如果密钥 $key$ 在 $A$ 发送给 $B$ 的时候被窃听了

这时窃听者就知道密钥,以此将密文解密,从而窃听消息。

非对称加密

非对称加密指的是加密的密钥和解密的密钥不是同一个密钥,我们把加密密钥称为公开密钥,因为它是可以公开的,任何人都可以访问到,我们称解密密钥为私有密钥。

当 $A$ 给 $B$ 发送消息时,在此之前,$B$ 会生成公开密钥和私有密钥,然后 $B$ 将公开密钥发送给 $A$,接着 $A$ 使用该公开密钥加密消息,并将消息发送给 $B$,当 $B$ 接收到消息之后,使用私有密钥对消息解密

即使窃听者窃听到了密文以及公开密钥,但是它没有私有密钥,所以它不能解密出消息。

但是这种方法并不是完美的,假设在 $B$ 向 $A$ 发送公开密钥时,窃听者将 $B$ 公开密钥修改为了自己的公开密钥发送给 $A$

因为公开密钥并不能指明来源是谁,当 $A$ 接收到密钥时误以为是 $B$ 的公开密钥,这样当 $A$ 向 $B$ 发送消息时,其实使用的是窃听者的公开密钥来加密消息,这时窃听者通过私钥解密,从而窃听到消息

并且再次使用 $B$ 的公开密钥加密消息,将消息发送给 $B$,对于 $A$ 和 $B$ 来说,它们完全没有意识到自己被窃听了

这种通过中途替换公开密钥来窃听数据的攻击方法叫做中间人攻击

非对称加密可靠性会出现问题就是因为 $A$ 无法判断接收到的密钥是否来自于 $B$,想要解决这个问题,就要用到后面讲到的数字证书。

混合加密

使用非对称加密虽然比对称加密安全,但是非对称加密方法加密和解密所需的资源以及时间比对称加密方法所需的资源和时间代价高很多,那么就有人提出一种加密方式,同时使用对称加密和非对称加密这种混合加密的方式,既能得到非对称加密的安全性,又能得到对称加密的快速性。

首先我们上面谈到对称加密时有讲到对称加密的缺点,那就是需要将加密的密钥在互联网上传输,而密钥有可能会被窃听者窃取。

如果我们使用非对称加密的方法来加密对称加密的密钥,这样对称加密的密钥就不会被窃听者窃取,因为窃听者没有私钥,然后在下面的通信过程中使用对称加密的密钥加密消息,因为我们只使用了非对称加密加密了对称加密所使用的密钥,而消息的加密都是通过对称加密的密钥加密的,所以不会存在速度慢的问题,这样既保证了安全性,又兼顾了加解密所需的资源和时间。

目前在网页中使用的 HTTPS 协议使用的就是混合加密的方式。

密钥交换算法

Diffie-Hellman 密钥交换可以解决使用对称加密方法进行通信时密钥被窃听的问题。在讲解该算法的消息过程之前,我们先了解一下该算法的概念。

该算法它可以合成两个密钥

并且合成的密钥有三个特点

  1. 已知其中一个密钥,无法根据合成的密钥推断出另一个密钥

  2. 合成的密钥可以继续与其他的密钥进行合成

  3. 密钥合成的结果与合成的顺序无关

现在我们就使用这种方法在 $A$ 和 $B$ 之间传递密钥,首先由 $A$ 生成密钥 $P$,然后将该密钥发送给 $B$,在这个过程中有可能被窃听者 $X$ 窃取到密钥,所以这时的密钥不能被用来加密消息

接着 $A$ 和 $B$ 各自生成自己的私钥 $SA$ 和 $SB$,并使用上述的合成方法与密钥 $P$ 进行合成,然后发送给对方,双方接收到对方合成的密钥后,再将密钥与自己的私钥合成,如下

最后,$A$ 得到密钥 $P|SB|SA$,而 $B$ 得到密钥 $P|SA|SB$,根据算法特点 $3$,合成的密钥与合成的顺序无关,所以二者的密钥是相同的,所以接下来 $A$ 和 $B$ 可以用该密钥来加密和解密消息。

那窃听者有可能窃听该密钥吗? 通过上面的动图我们知道窃听者掌握的信息有密钥 $P$,以及两个合成密钥 $P|SA$ 和 $P|SB$,根据算法特点 $1$,窃听者是无法推断 $SA$ 和 $SB$ 的,所以窃听者就不能合成出密钥 $P|SA|SB$。

消息认证码

消息认证码可以检测篡改,例如下面的场景

$A$ 向 $B$ 发送一个消息,在中途消息被恶意用户修改了,但是 $B$ 并没有意识到消息已经被修改了,以为接收到的消息就是 $A$ 发送的消息。消息认证码可以预防这种情况发生。

下面看一下使用消息认证码发消息的流程:

  1. $A$ 生成了一个生成消息认证码的密钥,并以安全的方式将密钥发送给了 $B$
  2. $A$ 根据消息内容(已加密),使用密钥生成一个值,这个生成的值就是消息认证码,简称 MAC(Message Authentication Code)
  3. $A$ 将消息和 MAC 发送给 $B$
  4. $B$ 根据接收到的消息,使用 $A$ 之前发送的密钥生成一个值,如果这个值与 $A$ 发送过来的 MAC 相同,则可以认为消息是没有被篡改过的
  5. 接下来只需要对密文解密即可

如果在中途 $X$ 对 $A$ 发送的消息进行了篡改,那么 $B$ 收到的密文和 $A$ 发送的密文不同,那么 $B$ 生成的消息认证码和 $A$ 发送的消息认证码就不相同,这个时候 $B$ 就知道消息被篡改过了,这时可以要求 $A$ 重新发送消息。

数字签名

消息认证码虽然解决了篡改的问题,但是因为他们使用的是相同的密钥加密和解密,所以 $B$ 也可以生成消息认证码,所以事后 $A$ 可以否认消息并不是他发的,因为不仅仅是他可以生成消息认证码(事情又不是我一个人可以干,你凭什么说是我干的)。

使用数字签名不仅可以解决篡改问题,还可以解决事后否认问题。假设 $A$ 给 $B$ 发送消息,我们首先看一下流程:

  1. $A$ 在发送前给消息加上数字签名,数字签名只能由 $A$ 生成
  2. $B$ 收到 $A$ 的消息,验证数字签名的正确性,但是无法生成数字签名

因为数字签名只能由 $A$ 生成,所以 $A$ 无法在事后否认(这件事情就你能干,不是你干的是谁干的)。

我们看一下使用数字签名通信的详细过程:

  1. $A$ 生成一对公钥和私钥,公钥是每个人都知道的,私钥是 $A$ 独有的,$A$ 使用私钥对消息(已加密后的消息)加密,得到数字签名
  2. $A$ 将消息以及数字签名发送给 $B$
  3. $B$ 使用 $A$ 的公钥对消息解密,得到一个数字签名,验证该数字签名与 $A$ 发送数字签名是否相同
  4. 数字签名确认无误,说明消息没有经过篡改,并且可以确认消息是 $A$ 发的,可以对消息解密得到明文

上述过程有两次加密,第一次加密是对明文进行加密,得到密文防止被窃听,第二次加密是根据密文生成数字签名。对应的也要进行两次解密,第一次解密是为了得到数字签名,从而验证数字签名的正确性,如果数字签名确认无误,那么就需要进行第二次解密,将密文变换为明文,得到真正的消息。

事实上,使用私钥对全部的消息进行加密比较耗费时间,一般是根据消息生成哈希值,然后对哈希值加密得到数字签名。

因为数字签名是使用私钥进行加密的,只有 $A$ 有私钥,所以 $A$ 无法事后否认。

在本小节比较强调数字签名在事后否认方面的作用,但是数字签名可以用来检测消息是否被篡改,因为数字签名的生成与消息的内容是有关的,如果消息被篡改了,那么生成的数字签名就不对,就可以得知消息被篡改了或者不是 $A$ 发送的消息。

数字证书

因为数字签名没有解决公开密钥制作者的问题,所以如果 $X$ 假冒 $A$ 给 $B$ 发送消息,此时 $X$ 会生成一对公钥和私钥,并且将公钥发送给 $B$,因为公钥中没有携带发送者的信息,$B$ 就会使用该公钥来验证数字签名,对于 $B$ 来说他以为自己在和 $A$ 通信,实际上在与 $A$ 通信。

解决这个问题需要使用数字证书,假设 $A$ 给 $B$ 发送消息,通信过程如下:

  1. $A$ 将包含公开密钥以及自己的相关信息(如邮箱)的个人资料发送给认证中心

  2. 认证中心根据 $A$ 的资料使用自己的私钥生成一个数字签名,并且将数字签名以及资料放进同一个文件中

  3. 认证中心将该文件发送给 $A$,该文件就是 $A$ 数字证书

  4. $A$ 将包含公开密钥的数字证书发送给 $B$,$B$ 收到证书后,首先对 $A$ 的身份进行确认(如邮箱是否是 $A$ 的邮箱),接着获取认证中心的公开密钥,使用认证中心的公开密钥对数字签名进行确认,判断是否是认证中心给出的签名

  5. 如果确认 $A$ 的信息无误,以及签名是认证中心的签名,那么就从证书中取出 $A$ 的公开密钥

如果这时 $X$ 假冒 $A$ 给 $B$ 发送它的公开密钥,这时 $B$ 没有必要信任以非证书的形式发送的公开密钥;这时 $X$ 为了假冒 $A$ 在认证中心登记自己的公开密钥,但是 $X$ 无法使用 $A$ 的信息(如邮箱),因此无法获得 $A$ 的证书。

通过数字证书,消息的接收者可以确认公开密钥的制作者。

但是目前还有一个疑问,$B$ 从认证中心得到的公开密钥真的来自于认证中心吗? 如果认证中心也是假冒的呢?

实际上,认证中心的公开密钥也是以数字证书的形式交付的,会有更高级别的认证中心对这个认证中心署名。

假设存在一个被社会广泛认可的认证中心 $A$,此时出现了一家新公司 $B$ 想开展认证中心业务,但是 $B$ 没有得到社会的认可,于是 $B$ 向 $A$ 申请发行数字证书,$A$ 会对 $B$ 是否能开展认证业务进行检测,如果通过了检测,$A$ 就会向 $B$ 发行证书,公司 $B$ 就可以向社会表示自己获得了公司 $A$ 的信任。

最顶端的认证中心被称为根认证中心,其自身的正当性由自己证明。如果根认证中心不被信任,整个过程就无法运转,所以根认证中心一般是大型企业或者与政府有关联且已经获得了社会信赖的组织。

参考资料

  • 《我的第一本算法书》