张三打算给李四写一封信,里面会提到一个天大的秘密。张三不想让第三个人知道那件事,但是这封信却一定要经过其他人才能送到李四手中。这时候张三和李四将面临三个问题:
如何保密信的内容?
如何保证李四收到的信中的内容没有被其他人修改过?
李四如何确定信的内容是张三本人写的?
一些说明:想要传递给他人的有效内容这里称为信息;传递时的基本单元这里称为消息,消息中包含信息和一些用于传递的附加内容。
信息加密
首先,我们来讨论保密信息的问题。
能够直接从中得到信息的消息称为明文;需要经过计算才能从中得到信息的消息称为密文。从明文到密文的计算过程称为加密;反之,则称为解密。把明文计算成密文的方法称为加密算法。
谍战片中经常出现的密码本就是一种经典的加密算法。在这类加密方案中,加密算法本身也是保密的。这类加密算法可以通过试探分析的方式破解。而现代加密方案则基于数学难题的难解性,加密算法本身已经不需要保密,配合保密的密钥实现加密。这样提高了加密算法的复用率。
如果加密和解密使用同一个密钥,则称为对称加密;如果加密和解密分别使用不同的密钥,则称为非对称加密。非对称加密的好处是可以减少单方面密钥泄露造成的信息泄露风险,特别试用于一方接收多方发送的消息收发模型中。非对称加密算法的计算效率一般比对称加密算法的计算效率低。
讨论完加密算法本身的问题,接下来讨论密钥分发的问题。有两种可行的方案:一是在传递消息之前已经通过可靠的途径获得了密钥;二是在消息传递前期磋商出一个临时的密钥。
密钥磋商算法基于这样的思路:张三和李四各生成密钥的一个计算因子,然后交换各自计算因子经过密钥磋商算法计算得出的结果作为下一步生成密钥的计算成分,之后再分别用各自的计算因子和收到的计算成分经过算法生成出最终的密钥。因为双方没有直接交换计算因子,所以中间人无法得到完整的密钥。需要注意的是,如果在密钥磋商前没有进行身份验证,那么中间人可以伪装自己分别跟双方磋商密钥。也就是说,密钥磋商只有在双方身份得到验证的前提下才有意义。密钥磋商一般用于采用对称加密算法的一次性密钥加密通信,通常密钥磋商过程中会生成三个随机数,两个计算因子,另一个用于交换计算成分。
关于加密还有一点需要说明,没有哪一种加密方案是永远完全可靠的,同时信息具有时效性。这样,只要能够保证在信息的时效内可靠的方案,就是合适的加密方案。
消息摘要
值得说明的是,加密算法一般不会关注消息的内容,也不应该关注消息的内容,因为加密是把明文变成密文的过程。也就是说,每一段明文在相应的密文中都应该有一段对应,反过来也是。这样,在只拿到密文的时候,即使没有密钥也可以通过丢弃部分密文段或者插入随意生成的密文段达到修改消息内容的目的,这样就造成了解密后的消息内容混乱。
摘要算法帮助解决了这个问题。摘要算法可以保证内容和摘要值一一对应。这样,只要能拿到有效的摘要值即可验证消息的完整性,相当于纸质文件的骑缝章。
接下来又有了新的问题,如何传递摘要值?一种有效的方法是加密。张三将信息的摘要值的加密后的密文包含在消息中,一同发送给李四。李四在收到消息后,比较对摘要值密文解密得到的摘要值和对消息内容计算摘要得到的摘要值,如果相同则消息内容完整,否则说明消息内容不完整。
上面的操作在结合了下一节将讨论的身份验证之后被称为签名和验签。签名对内容完整性的保证基于下面的思路:摘要值和内容一一对应,故修改内容也要同时修改摘要值。而在没有密钥的前提下是无法生成有效的密文的。除非使用的算法有漏洞,否则可以认为消息的内容得到了完整性的保证。
身份验证
在讨论了消息内容保密和完整性之后,我们该来讨论一下确认身份的问题了。
李四如何判断对面的张三真的就是张三呢?通常李四凭借之前掌握的张三这个人的特征来验证张三的身份,比如相貌、行为习惯等。参考这样的模式,我们也可以给张三制造一些不易被复制的特征。如果能在消息中体现这些特征,那么就可以用于验证身份,相当于签字画押。
在前面的讨论中发现加密算法具有不可通过明文和密文计算密钥的性质,那么这时密钥即可作为一种身份特征。
如果张三在发送的消息中既包含了内容的明文也包含了内容的密文,那么李四就可以用事先保存的张三的身份密钥解密密文或者加密明文来验证张三的身份。这种方式的一个问题是,如果明文内容比较固定,那么中间人就可以保存明文和密文的对应,用于伪造身份。所以更好的方式是李四发送随机明文,张三回复用自己身份密钥加密后的密文。
需要强调的是,身份密钥必须事先通过安全途径获得。如果在传递消息的过程中分发身份密钥,则可能被中间人替换。这种中间人替换或伪造身份还有前面提到的修改消息内容的行为被称为中间人攻击。
如果张三李四使用对称加密用于鉴定身份,那么这个身份密钥就只能保存在他们两个人手中,双方都可以用此密钥作为对方身份的凭证。但是如果将此密钥分发给了第三个人,那么这时的身份将变得不明确。基于此,身份验证通常采用非对称方案。这样,张三只要保管好自己的身份私钥,然后将公钥分发给其他人,其他人就可以使用这个密钥来验证张三的身份了。与加密相反,在一方发送多方接收的模型中,更应该采用非对称身份验证。在多客户端单服务端的模型中,对客户端的认证可以采用对称认证方案,类似使用账户和密码登录的情况;而对服务端的认证则采用非对称方案更合理。
到这里,还有一个问题没有解决,如何在无法确定安全的渠道下使传递的身份公钥有效?一个可行的方案是借助第三方。也就是找一个可靠的人鉴定另一个人是不是可靠。张三将身份公钥和鉴定人信息以及鉴定人对张三身份信息的签名打包在一起传递给李四,李四就可以通过验证鉴定人的签名进而验证张三的身份了。这种包含身份信息和认证机构信息以及认证签名信息的消息被称为证书,证书中还可能包含一些其他信息,比如用于通信的加密公钥等,但不会也不应该包含保密信息。证书的有效性可以通过查询认证机构验证。同样,认证机构也需要证书,他们的证书由上级认证机构颁发。这样,只要能够保证顶级证书有效,就可以通过信任的向下传递验证所有的证书了。
总结
假想一个场景:张三向李四发送一个包含随机数的消息,请求验证李四的身份。李四用自己的身份私钥对收到的随机数加密,并将加密后的密文和自己的证书发回给张三。张三首先验证李四证书的有效性,再用证书中的身份公钥解密李四发来的密文,并比对内容。接下来只要双方各生成一个计算因子,并交换各自计算因子对于之前那个随机数的计算结果,即可磋商出一个临时的密钥。这个密钥既用来对信息加密,也用来验证身份。在接下来的通信中,发送消息前先对信息加密,再计算加密后信息的摘要值并对摘要值加密,可以看作是签名,最后将信息密文和摘要值密文作为消息发送;收到消息后,先验证摘要再解密出信息。对信息密文签名而不是对明文签名的好处是,如果消息被破坏,则可以减少一次解密操作。