散列函数的另一种用法与报文鉴别有关。
有时候,通信双方不仅关心通信内容的私密性,对信息是否被篡改过(内容完整性)更为关心;或者,他们根本不关心信息的私密性而只关心信息的完整性。亦或者,软件的不同层次可能负责不同的任务,比如底层负责加解密,上层完成完整性鉴别。报文鉴别码可以解决这类需要。
报文鉴别码,英文是Message Authentication Code,简写为MAC(注意它跟计算机网络技术中“MAC地址”的那个“MAC”没有任何关系)。
本质上,MAC就是加了密的消息摘要。而所谓“消息摘要”,就是某个散列函数针对一条消息所计算的结果。还记得吗?散列函数的结果是定长的,而且相对较短,比如512bit的消息摘要已经有很高的安全强度了(MD5的输出只有128bit)。
首先,通信双方共享一个密钥。然后,由于通信双方并不关心通信内容的私密性,或者觉得没必要也不愿意付出每次加/解密全部消息的代价。于是,他们并不用密钥加密全部内容,而只是加密基于报文计算出的摘要,这个加了密的摘要就是MAC。如:MAC = DESK(SHA(M)),即使用密钥K,将消息M的SHA散列值用对称加密算法DES算法加密。
计算出MAC之后,发送消息时顺便把它附上。接收方在收到之后,可以用共享的密钥解出其中的散列值,然后基于消息重新计算散列值并比刚刚解密得到的散列值进行比较,如果两者一致,就表明消息没有被篡改过。
讲到这里,有必要总结一下,我们所说的“报文”或“消息”是一个意思,对应的英文单词都是“message”,本文同时使用了两种只是为尊重不同上下文或专有名词中的惯用译法。另外一个类似的词是“摘要”,其实它指的就是消息或报文的散列值。以下同。
了解了报文签别码,理解数字签名(Digital Signature)就不难了。注意消息签别码只能用于验证消息的完整性,并不能提供防抵赖的鉴别和认证功能。而数字签名,正如笔迹签名,却可以提供这样的功能。
如果说MAC是对称加密与散列函数的结合,那数字签名就是非对称加密与散列函数的结合。
本质上,一个数字签名就是用私钥加密的消息散列值,比如DS = RSAKR(SHA(M)),即使用私钥KR,将消息M的SHA散列值通过非对称加密算法RSA加密。
说到这里,大家应该能够想到如何验证一个数字签名了。由于与KR对应的公共密钥KU是公开的,任何人都可以解开这个签名,从而得到SHA(M),然后,验证的人基于收到的消息M重算SHA摘要,如果算出来的结果跟刚刚解密得到的相同,就可以确定报文是由该密钥对的持有者发出的。
显然,数字签名的安全性主要依赖于散列算法的强度(单向、抗碰撞)、非对称加密算法的安全性,以及非对称密钥的强度(从一个密钥推导另一个密钥的难度)。
与本文(二)中提到的密码保存机制一样,以上讲的仍然只是基本原理,在实际的数字签名中,被签名的信息不仅包括报文本身,往往还有其它一些附加信息,如时间戳、随机数等,具体的签名和验证机制也会包含更多实现细节。
此外,以上解释报文鉴别码和数字签名时,都未提到数据的保密性,这并不代表在这些场合数据私密性不重要,而是说报文鉴别和数字签名解决的并不是保密问题,而是其它的问题。在实际应用中,如果数据私密性也很重要,它们完全可以跟对称加密算法甚至非对称加密算法进一步结合使用。
基于上一节的讨论,数字签名主要依赖两种技术:非对称加密和散列算法。散列算法相对独立,它的结果只依赖于消息本身,而不依赖任何其它机密信息。于是,要使签名可认证(比如凭什么说这是张三的签名,而非李四的签名),关键就在于非对称加密这一边。
对一个普通人来讲,通常他一不具备信息安全的专业知识,二也没有实际能力来维护一个公私钥对(比如不知轻重地随便写在纸上弄丢了)。于是,一些专门负责密钥对创建、维护和认证的机构应运而生。这些机构具有权威的专业知识,懂得如何创建各种密钥对,有能力维护不同用户的密钥,在需要的时候还能验证密钥或签名的有效性。这样的机构即称为证书权威机构(Certificate Authority, CA)。CA的主要职能就是签发数字证书(Digital Certificates)。CA在公共密钥基础设施中充当“可信第三方”。对一个基于数字证书的签名来讲,只有当签名者和验证者都信任这个第三方时,签名才具有实际意义。
一份数字证书包含很多信息,较重要的信息包括:签名算法标识、有效期,颁发者(CA)、主体标识(证书颁发给谁),主体的公开密钥,CA的数字签名。
大家可能注意到了,为数字签名提供必要信息的数字证书中本身又包含了一个数字签名。这一个数字签名不是主体(或证书持有人)的数字签名,而是CA对这份证书的签名。注意CA的签名可以不必再基于其它证书,它所基于的算法细节和公开密钥信息可通过其它方式直接发布。
认证方只要信任这家CA,就可以通过验证证书中的数字签名来判断这份证书的有效性;在验证了证书的有效性之后,便可直接取用证书中的公开密钥信息,从而验证某个签名是否真的来自证书的持有者。
在实际应用中,CA可以分成不同的级别,每个级别的有效性由它的上一级来认证,从而形成多级的“认证链”,而位于认证链顶端的最后一份证书称为“根证书”。根证书的验证不再依赖其它证书,因此,你只能无条件信任根证书的颁发者,否则这一切都没有意义。
世间没有绝对的可靠,想要验证一些东西,总得信任一些东西。这有点像数学,想要推导一些东西,总得无理头地相信(或假设)一些东西——即无需推导“自然”成立的所谓的“公理”。