公钥加密、数字签名、消息认证

网络安全的几个问题

一、网络是开放的,在上面要发送一段内容,随时可能被其他人拦截看到,因此需要加密。
最初想到的是对称加密,可以通过同一个密钥加密,也可以通过同一个密钥解密。(比如加密字符串,加密时每个字符ASCII码同时加2,解密时ASCII同时减2,在这里密钥就是2,而ASCII的操作称作加密解密算法,加密前的字符串称为明文,加密后的字符串称为密文)
但是对称加密有一个问题:通信双方在网络通信之前,需要先知道加解密算法和密钥。在生活中我们可以通过打电话,或者见面之类的方式。但是每一次通信都需要这样交流一次,这显然不是我们所期望的。
解决办法便是公钥加密

二、接收方接收到一个密文,他并不知道是谁发送给他的,或者说他无法确定是发送方本人发送的。黑客完全可以拦截发送方的密文,然后发送给接收方不同的密文,并自称是接收方发送的。
解决办法便是数字签名

三、即使黑客无法解开密文,但是他还是可以拦截密文和修改密文的。倘若黑客不想让接收方接收到正确的明文,每次都直接修改没有破解的密文,接收方即使可以解密,但是由于密文已经被修改过,因此也得不到正确的明文。那么接收方如何知道内容是否被修改过呢?
解决办法便是消息认证

公钥加密

公钥加密中有两个密钥——公钥和私钥,使用公钥进行加密的密文只能使用私钥进行解密,通过私钥进行加密的密文只能使用公钥进行加密。
公钥人人都可以得到,但是私钥只有自己有。
加密过程如下图,首先确认接收方是Bob,因此Bob拥有自己的私钥,那么发送方就需要使用Bob的公钥进行加密,在Bob接收到之后,直接用自己的私钥解密即可得到明文。
这里写图片描述

数字签名

由于接收方公钥人人都可以获得,因此人人都可以发消息给接收方。那么接收方如何确定接收方是本人呢?数字签名就解决了这个问题。
在使用公钥加密之前,首先使用自己的私钥对明文进行加密。这样接收方在使用自己私钥解密之后,再使用接收方的公钥进行解密,那么正常情况下就可以得到正确的明文了,并且也确认了发送方的身份。

那么为什么不是先用接收方公钥加密,然后再用发送方私钥加密么?
理论上也是可行的,但是就类似写信一样,一般我们签名都会在信封内部,直接签名在信封上的很少吧?

消息认证

消息认证的目的:如果密文被修改过了,那么接收方可以通过认证技术知道自己的密文被修改过。
认证实现的方式理解也比较简单:主要是通过认证函数,假设明文为M,认证函数生成的认证值为V,那么最终发送的内容就是M+V。

那么什么是认证函数呢?认证函数主要分为三类:

消息加密函数:

用完整信息的密文作为对信息的认证。通过对明文M加密后生成V。接收方接收到消息之后,把V解密,如果M和V解密后的内容相同,那么内容就是没有被修改过。
这种方法有一个很大的劣势,比如明文的大小为1G,那么生成的认证值也会为1G,而且由于本身明文比较大,加密过程也会比较耗时,所以这种方法认证的代价是比较大的。

消息认证码:

是密钥和消息的公开函数,产生一个固定长度的值V作为认证标识。接收方接收到消息之后,仍然是通过这个公开函数得到认证标识,如果最终的结果和接收到的V相同,那么内容就是没有被修改过。

散列函数:

是一个公开函数,它将任意长的信息映射成一个固定长度的信息,作为认证值V,比如MD5。接收方接收到消息,明文通过散列函数得到散列值,对比得到的V查看是否相同,如果相同,那么内容就是没有被修改过。