第3 章公钥密码和消息认 证 3.1 消息认证方法 3.2 安全散列函数 3.3 消息认证码 3.4 公钥密码原理 3.5 公钥密码算法 3.6 数字签名 3.7 关键词、思考题和习题 学习目标 学习完这一章后,你应该能够: z 定义术语消息认证码 。 z 列出并解释消息认证码的基本要求 。 z 解释为什么用在消息认证码中的散列函数必须是安全的 。 z 理解原像攻击、第二原像攻击和碰撞攻击之间的区别 。 z 理解SHA-512 的操作 。 z 给出HMAC 的概述 。 z 给出公钥密码系统基本原则的概述 。 z 解释公钥密码系统两种不同的用途 。 z 给出RSA 算法的概述 。 z 定义Diffie-Hellman 密钥交换协议 。 z 理解中间人攻击方法 。 除消息机密性外,消息认证也是一个重要的网络安全功能。本章分析消息认证的三个 方面。首先,研究使用消息认证码(MAC)和散列函数进行消息认证。然后分析公钥密码 原理和两个具体的公钥算法。这些算法在交换常规公钥时非常有用。最后分析使用公钥密 码生成数字签名,从而提供了加强版的消息认证。 3.1 消息认证方法 加密可以防止被动攻击(窃听)。加密的另一个要求是可以防止主动攻击(伪造数据和 业务)。防止这些攻击的办法被称为消息认证。 当消息、文件、文档或其他数据集合是真实的且来自合法来源,则称其为可信的。消 息认证是一种允许通信者验证所收消息是否可信的措施。认证包括两个重要方面:验证消 网络安全基础:应用与标准(第6 版) 息的内容有没有被篡改和验证来源是否可信1。还可能希望验证消息的时效性(消息有没有 被人为地延迟或重放)以及两实体之间消息流的相对顺序。这些问题属于第1 章介绍的数 据完整性范畴。 3.1.1 利用常规加密的消息认证 仅简单地使用常规加密似乎也可以进行消息认证。假设只有发送方和接收方共享一个 密钥(这是合理的),那么假定接收方能够识别有效消息时,只有真正的发送方才能够成功 地为对方加密消息。此外,如果消息里带有错误检测码和序列号,则接收方能够确认消息 是否被篡改过和序列号是否正常。如果消息里还包含时间戳,则接收方能够确认消息没有 超出网络传输的正常延时。 事实上,对数据认证而言只使用对称加密的方法不是一个合适的工具。一个简单的例 子是,在分组加密算法的ECB 工作模式下,攻击者重排密文分组次序后每一个分组仍然能 被成功地解密。虽然在某些层级(例如各IP 包)可以使用序列号,但通常情况下一个单独 的序列号不一定与明文中的每个b比特分组发生联系。因此,分组的重排是一种威胁。 3.1.2 非加密的消息认证 本节分析几种不依赖于加密的消息认证方法。所有这些方法都会生成认证标签,并且 附在每一条消息上用于传输。消息本身并不会被加密,所以它在目的地可读而与目的地的 认证功能无关。 由于本节讨论的方法并不加密消息,所以不提供消息的保密性。正如上面所指出的, 通过对消息自身的加密并不能提供一种安全的认证形式。然而,在一个单一算法中通过加 密消息并附上认证标签的方法把消息的认证和保密结合起来是可能的。通常,消息认证与 消息加密是两个独立的功能。[DAVI89] 给出了三种无须保密的消息认证情况: (1)许多应用需要把相同的消息广播到多个目的地。其中两个例子就是:通知当前的 用户网络不可使用和控制中心的警报信号。只由一端负责监控的认证既经济又安全。因此, 消息必须以带有相关消息认证标签的明文形式进行发送。负责监控的系统执行认证。一旦 出现冲突,则普通的警报信号就会警告其他目的端系统。 (2)在信息交换中,另一种可能的情况是通信某一端的负载太大,没时间解密所有传 入的消息。这时就会有选择的随机抽取消息进行认证。 (3)对明文形式的计算机程序进行认证是很有意义的工作。这些程序不用每次都进行 解密就可以运行,从而节省了处理器资源。然而,如果程序含有消息认证标签,则当消息 完整性需要确认的时候要进行认证。 可见,在满足安全需求上认证和加密都有其应用场所。 消息认证码。一种认证技术利用私钥产生一小块数据,称之为消息认证码,将其附到 消息上。该技术假设两个通信实体(如A 和B)共享一个公共密钥KAB 。当A 有消息要发 送给B 时,A 计算消息认证码(MAC)作为消息和密钥的一个函数:M ( AB, M) 。 , MAC = FK 1 为简单起见,本章余下部分统称消息认证,它既表示被传输消息的认证,也表示存储数据的认证(数据认证)。 第3 章公钥密码和消息认证 消息连同MAC 被一起传送给预定接收方。接收方对接收到的消息使用相同的密钥做相同运 算,生成新的MAC。比较收到的MAC 和计算得到的MAC(见图3.1)。假设只有接收方和 发送方知道密钥,若收到的认证码与计算得到的认证码相吻合,则可得出下列结论: (1)接收方能够确认消息没有被篡改。如果攻击者篡改消息却没有改变相应的MAC, 则接收方计算的MAC 不同于收到的MAC。因为假设攻击者不知道密钥,他不能修改MAC 使其与改动后的消息保持一致。 (2)接收方能够确保消息来自合法的发送方。因为没有其他人知道密钥,所以他们就 不能生成具有正确MAC 的消息。 (3)如果消息中包含序列号(如X.25、HDLC 和TCP 使用的序列号),而攻击者不能 成功地修改序列号,那么接收方就可以确认消息的正确序列。 图3.1 使用消息认证码(MAC )的消息认证 许多算法都可以生成MAC,NIST 标准FIPS PUB 113 推荐使用DES。DES 可以生成加 密形式的消息,密文的最后几个比特用作MAC。典型的有16 或32 比特的MAC。 前面描述的过程类似于加密。不同点是认证算法不需要可逆,而可逆对于解密则是必 需的。可以看出,由于认证函数的数学特性,与加密相比它更不容易被攻破。 单向散列函数。MAC 的一种替代方法是使用单向散列函数。如同MAC,散列函数接 收变长的消息M 作为输入,生成定长的消息摘要H(M)作为输出。与MAC 不同的是散列函 数不需要密钥输入。为了认证消息,消息摘要随消息一起以可信的形式传送。 图3.2 显示了消息认证的三种方式。消息摘要可用传统密码(见图3.2(a));如果只有 发送方和接收方共享密钥,则保密性是能保证的。消息也可以用公钥方式加密(见 图3.2(b));这将在3.5 节进行讲述。公钥方法有两个优势: (1)既能提供数字签名又能提供消息认证; (2)不需要在通信各方之间分发密钥。 这两种方法与那些加密整个消息的方法相比具有一定的优势,因为它们只需很少的计 算量。所以开发一种无须整体加密的技术很有吸引力,其原因在[TSUD92] 中给予了说明: 网络安全基础:应用与标准(第6 版) 图3.2 使用单向散列函数的消息认证 z 软件加密速度非常低。虽然每条消息需加密的数据量很少,但是也可能会形成一个 稳定的消息流输入和输出系统。 z 硬件加密成本不容忽视。用廉价芯片实现DES 是可行的,但如果网络中的所有节点 都必须有该硬件,则总成本太大。 z 硬件加密对大批量数据来说具有优势。但对于小块数据,将会有大量时间花费在前 期的初始化/调用上面。 z 加密算法可能受专利保护。 图3.2(c)是一种使用了散列函数但是没有使用加密的消息认证技术。这一技术假设 通信双方(例如A 和B)共享秘密值S 。当A 要给B 传送消息时,A 计算秘密值与消息 串接后的散列函数:MDM = H(SAB||M)1。然(AB) 后发送[M||MDM]给B。由于B 拥有SAB,它能重 || 表示串接。 第3 章公钥密码和消息认证 新计算H(SAB||M),验证MDM。因为秘密值本身并不会发送,所以攻击者不可能修改所截获 的消息。只要不泄露秘密值,攻击者就不可能生成伪消息。 第三种技术的一种变体称作HMAC,在 IP 安全中使用了该认证方法(在第9 章中描 述);对SNMPv3 也有描述(见第13 章)。 3.2 安全散列函数 单向散列函数或安全散列函数之所以重要,不仅在于消息认证,还有数字签名。本节 从安全散列函数的要求开始讨论,然后研究最重要的散列函数:SHA。 3.2.1 散列函数的要求 散列函数的目的是为文件、消息或其他数据块产生“指纹”。为满足在消息认证中的应 用,散列函数H 必须具有下列性质: (1)H 可适用于任意长度的数据块。 (2)H 能生成固定长度的输出。 (3)对于任意给定的x,计算H(x)相对容易,并且可以用软/硬件方式实现。 (4)对于任意给定值h,找到满足H(x)=h 的x 在计算上不可行。满足这一特性的散列 函数称为具有单向性,或具有抗原像攻击性1。 (5)对于任意给定的数据块x,找到满足H(y) = H(x)的y ≠ x 在计算上是不可行的。满 足这一特性的散列函数被称为具有抗第二原像攻击性,有时也称为具有抗弱碰撞攻击性。 (6)找到满足H(x) = H(y) 的任意一对(x,y)在计算上是不可行的。满足这一特性的散 列函数被称为抗碰撞性,有时也被称为抗强碰撞性。 前三个性质是使用散列函数进行消息认证的实际可行要求。第四个属性,抗原像攻击, 是单向性:给定消息容易产生它的散列码,但是给定散列码几乎不可能恢复出消息。如果 认证技术中使用了秘密值(见图3.2(c) ,则单向性很重要。秘密值本身并不会传输;然 而,假如散列函数不是单向的,而攻击者能够分析或截获消息M 和散列码C=H(SAB||M),则 攻击者很容易发现秘密值。攻击者对散列函数取逆得到SAB||M=H-1(C)。因为这时攻击者拥 有M 和SAB||M,所以他们可以轻而易举地恢复SAB 。 抗第二原像攻击性质保证了对于给定的消息,不可能找到具有相同散列值的可替换消 息。利用加密的散列码可防止消息被伪造(见图3.2(a)和图3.2(b) 。如果该性质非真, 则攻击者可以进行如下操作:第一,分析或截获消息及其加密的散列码;第二,根据消息 产生没有加密的散列码;第三,生成具有相同散列码的可替换消息。 满足上面前5 个性质的散列函数称为弱散列函数。如果还能满足第6 个性质则称其为 强散列函数。第6 个性质可以防止像生日攻击这种类型的复杂攻击。生日攻击的细节超出 了本书的范围。这种攻击把m 比特的散列函数的强度从2m 简化到2m/2 。详细内容可参考 [STAL11]。 1 对f(x) = y,称x 为y 的一个原像。除非f 是一一映射,否则对给定的y,可能会有多个原像存在。 网络安全基础:应用与标准(第6 版) 除提供认证之外,消息摘要还能验证数据的完整性。它与帧检测序列具有相同的功能: 如果在传输过程中,意外地篡改任意比特,消息摘要则会出错。 3.2.2 散列函数的安全性 正如对称加密,也有两种方法可以攻击一个安全散列函数:密码分析法和蛮力攻击法。 对于对称加密算法,密码分析法利用了该算法在逻辑上的缺陷。 散列函数抵抗蛮力攻击的强度完全依赖于算法生成的散列码长度。攻击一个长度为n 的散列码所需要付出的代价如下: 抗原像2n 抗第二原像2n 抗碰撞2n/2 如果需要抗碰撞(即一般安全散列码所需要的),则数值2n/2 是抗蛮力攻击能力的一个 度量。Van Oorschot 和Wiener[VANO94] 曾经提出,花费1000 万美元设计一个被专门用来搜 索MD5 算法(散列长度为128 比特)碰撞的机器,则平均在24 天内就可以找到一个碰撞 (这一结果是2004 年之前的情况。2004 年8 月中国密码学家王小云教授等首次公布了提出 一种寻找MD5 碰撞的新方法。目前利用该方法用普通微机数分钟内即可找到MD5 的碰撞。 MD5 已被彻底攻破。有关这方面情况,读者可参考其他资料——译者注)。因而,128 比特 的散列长度仍然不够。今后,一个散列码可能会是32 比特的序列,它的散列长度为160 比 特。对于160 比特的散列长度,同样的搜索机器要花费超过4000 年的时间才能找到一个冲 突。在当今的技术下,搜索时间可能会缩短许多,所以160 比特的散列长度现在看来也有 些不可信。 3.2.3 简单散列函数 所有散列函数都按照下面基本原理操作。把输入(消息、文件等)看成n 比特块的序 列。对输入用迭代方式每次处理一块,生成n 比特的散列函数。 一种最简单散列函数的每一个数据块都按比特异或。这可以用下式表示: Ci = bi1 ⊕ bi2 ⊕.. ⊕ bim 其中 : Ci 为散列码的第i 比特,1 i; ≤ ≤ n m 为输入中n 比特数据块的数目; bij 为第j 块的第i 比特; ⊕ 为异或操作。 图3.3 说明了这种操作;它为每一比特位置产生简单的奇偶校验,这称为纵向冗余校验。 这种校验对于随机数据的完整性检验相当有效。因为每个n 比特的散列值都有相同的可能 性,所以数据出错却不改变散列值的概率是2.n 。随着可预测的格式化数据增多,函数的有 效性越来越差。例如,在大多数标准的文本文件中,每个8 位字节的高阶比特总是零。因 第3 章公钥密码和消息认证 此,如果使用128 比特的散列值,则作用于该类型数据块的散列函数的有效概率为2.112 , 而不是2.128 。 图3.3 使用按比特异或的简单散列函数 对上面的方案进行改进的一种简单方法是在每个数据块处理后,对散列值循环移动或 旋转1 比特。其步骤归纳如下: (1)最初将n比特散列值设置为零。 (2)如下连续处理每个n比特的数据块: a. 将当前的散列值向左旋转1 比特。 b. 异或数据块生成散列值。 这些操作会使输入数据随机化得更加彻底,消除了输入中出现的任何规则性。 虽然步骤(2)提供了很好的数据完整性方法,但如图3.2(a)和图3.2(b)所示,当 加密散列码和明文消息一起使用时,它对于数据安全性几乎不起作用。给定一个消息,很 容易生成新的具有相同散列码的消息:简单地准备希望替换的消息,然后附加上n比特的 数据块,迫使新消息连同该数据块生成期望的散列码。 如果仅仅对散列码加密,简单异或或者旋转异或(RXOR)不够安全。但是如果连同散 列码一起加密消息,可能会觉得这个简单函数还是有用的。但是必须非常小心。最初由美 国国家标准局提出的一项技术就是对64 比特消息块进行简单异或操作,然后用密码分组链 接(CBC)模式加密整条消息。可以如下定义该方案:给定由64 比特分组,,.., X XX 序列组成的消息,定义散列码C为逐块异或或者所有分组的异或,再把得到的散(1) 列(2) 码附加(N) 上 作为最后一个模块: CX+ = X⊕ X ⊕.. ⊕ X = 然后,用CBC模式把整条消息和散(1) 列码(1) 一起(2) 加密,(N) 生(N) 成加密后的消息YY" Y+ 。 ,, [JUEN85]指出了操作消息密文而不会被散列码检测到的几种方法。例如,根据CBC(1) ((2) 见图2.(1) 9)(N) (,) 定义,有: X1 = IV ⊕ DKY ( , 1) Y ⊕ (,) Xi = i.1 DKY i Y ⊕ (, ) XN+1 = N DKY N+ 1 但是散列码XN+1 : XN+1 = X1 ⊕ X2 ⊕.. ⊕ XN [IV ⊕ D(, KY1)] ⊕[1 ⊕ KY 2)] ⊕.. ⊕ YN.1 ⊕ D(, N = Y D(, [ KY)] 因为上述等式中的项可以按任意顺序进行异或,所以如果对密文分组进行置换则散列 网络安全基础:应用与标准(第6 版) 码不变。 3.2.4 SHA 安全散列函数 近些年,应用最为广泛的散列函数是安全散列算法(SHA)。由于其他每一种被广泛应 用的散列函数都已被证实存在着密码分析学中的缺陷,截止到2005 年,SHA 或许是最后仅 存的标准散列算法。SHA 由美国国家标准与技术研究所(NIST)开发,并在1993 年公布 成为美国联邦信息处理标准(FIPS 180)。当人们发现SHA 中也存在缺陷之后(目前已知在 SHA-0 中存在),FIPS 180 的修订版本FIPS 180-1 于1995 年公布出来,通常称为SHA-1。 现行的标准文献被命名为“安全散列标准”。SHA 是基于散列函数MD4,并且其构架跟MD4 高度相仿。RFC 3174 中也列出了SHA-1 ,但它实质上是FIPS 180-1 的复制品,只是增加了 C 语言代码实现。 SHA-1 生成160 比特的散列值。2002 年,NIST 制定了修订版本的标准:FIPS-2 。它定 义了三种新版本的SHA,散列长度分别为256 、384 、512 比特,分别称为SHA-256 、SHA-384 、 SHA-512 ,三者并称为SHA-2。这些新版本使用了与SHA-1 相同的底层结构和相同类型的 模运算以及相同的二元逻辑运算。2008 年发布出来的修订文献FIP PUB 180-3 增加了224 比特的版本(如表3.1 所示)。RFC 4634 中也列出了SHA-2,但它实质上是FIPS 180-3 的复 制品,只是增加了C 语言代码实现。 表3.1 SHA 参数的比较 SHA-1 SHA-224 SHA-256 SHA-384 SHA-512 消息摘要大小160 224 256 384 512 消息大小< 264 < 264 < 264 < 2128 < 2128 块大小512 512 512 1024 1024 字大小32 32 32 64 64 步骤数80 64 64 80 80 注:所有的大小以比特衡量。 2005 年,NIST 宣布计划到2010 年不再认可SHA-1 ,转为信任SHA-2。此后不久,有 研究团队描述了一种攻击方法,该方法可以找到产生相同SHA-1 的两条独立的消息,它们 只用269 次操作,远少于以前认为找到SHA-1 碰撞所需的280 次操作[WANG05] 。这个结果 将加快SHA-1 过渡到SHA-2(该段描述的情况有误。2005 年,王小云教授等提出了对SHA-1 的攻击,使得找到碰撞的复杂度降到269 次操作,之后又降到263 次操作。这些结果迫使NIST 在2006 年宣布2010 年后不再推荐使用SHA-1——译者注)。 本节对SHA-512 做一介绍,其他SHA 算法与之很相似。 该算法以最大长度不超过2128 比特的消息作为输入,生成512 比特的消息摘要输出。 输入以1024 比特的数据块进行处理。图3.4 描述了处理消息生成摘要的全过程。处理过程 包括以下步骤: z 第1 步:追加填充比特。填充消息使其长度模1024 同余896[ 长度≡896( 模1024)] 。 即使消息已经是期望的长度,也总是要添加填充。因此,填充比特的范围是1~1024 。 第3 章公钥密码和消息认证 填充部分是由单个比特1 后接所需个数的比特0 构成。 z 第2 步:追加长度。将128 比特的数据块追加在消息上。该数据块被看作128 比特 的无符号整数(高位字节在前),它还含有原始消息(未填充前)的长度。 前两步生成了长度为1024 比特整数倍的消息。在图3.4 中,被延展的消息表示为 1024 比特的数据块序列M1, M2,.., MN ,所以延展后消息总长度为N×1024 比特。 图3.4 用SHA-512 生成消息摘要 z 第3 步:初始化散列缓冲区。用512 比特的缓冲区保存散列函数中间和最终结果。 缓冲区可以是8 个64 比特的寄存器(a、b、c、d、e、f、g、h)。这些寄存器初始 化为64 比特的整数(十六进制值) : a=6A09E667F3BCC908 e=510E527FADE682D1 b=BB67AE8584CAA73B f=9B05688C2B3E6C1F c=3C6EF372FE94F82B g=1F83D9ABFB41BD6B d=A54FF53A5F1D36F1 h=5BE0CDI9137E2179 这些值以逆序的形式存储,即字的最高字节存在最低地址(最左边)字节位置。这 些字的获取方式如下:前8 个素数取平方根,取小数部分的前64 位。 z 第4 步:处理1024 比特(128 字)的数据块消息。算法的核心是80 轮迭代构成的 模块;该模块在图3.4 中标记为F,图3.5 说明其逻辑关系。 每一轮都以512 比特的缓冲区值abcdefgh 作为输入,并且更新缓冲区内容。在第一 轮时,缓冲区里的值是中间值Hi.1 。在任意第t 轮,使用从当前正在处理的1024 比 特的数据块( M )导出的64 比特值t每一轮还使用附加常数Kt, t79 W 。其中0 ≤ ≤ 表 示80 轮中的某(i) 一轮。这些常数的获取方式如下:前8 个素数取立方根,取小数部 分的前64 位。这些常数提供了64 位随机串集合,可以初步消除输入数据中的任 何规则性。第80 轮输出加到第1 轮输入(Hi.1 )生成Hi 。缓冲区里的8 个字与Hi.1 中相应的字进行模264 加法运算。 z 第5 步:输出。当所有N 个1024 比特的数据块都处理完毕后,从第N 阶段输出的 网络安全基础:应用与标准(第6 版) 便是512 比特的消息摘要。 图3.5 SHA-512 处理单个1024 比特的数据块 SHA-512 算法使得散列码的任意比特都是输入端每1 比特的函数。基本函数F 的复杂 迭代产生很好的混淆效果;即随机选取两组即使有很相似的规则性的消息也不可能生成相 同的散列码。除非SHA-512 隐含一些直到现在还没有公布的弱点,构造具有相同消息摘要 的两条消息的难度的数量级为2256 步操作,而找出给定摘要的消息的难度为2512。 3.3 消息认证码 3.3.1 HMAC 近年来,人们对从加密散列码(如SHA-1)中开发MAC 越来越感兴趣。这种兴趣的动 机是: z 采用软件实现时,加密散列函数执行速度比传统密码算法(如DES)快。 z 有许多共享的密码学Hash 函数代码库。 诸如SHA-1 这样的散列函数并不是专为MAC 而设计的,因为散列函数不依赖于密钥, 所以它不能直接用于此目的。已经有很多方案可以把密钥合并到现有的散列算法中。最被 广泛接受的方案就是HMAC [BELL96a 、BELL96b]。HMAC 已经发布为RFC 2104 标准, 它是IP 安全中必须实现的MAC 方案。HMAC 也被用于其他Internet 协议,如传输层安全 (TLS,即Transport Layer Security ,它将很快取代安全套节字层)和安全电子交易(SET, 第3 章公钥密码和消息认证 即Secure Electronic Transaction)。 HMAC 的设计目标。RFC 2104 为HMAC 列出了下列设计目标。 z 不必修改而直接使用现有的散列函数。特别是很容易免费得到软件上执行速度较快 的散列函数及其代码。 z 嵌入式散列函数要有很好的可移植性,以便开发更快或更安全的散列函数。 z 保持散列函数的原有性能,不发生显著退化。 z 使用和处理密钥简单。 z 如果已知嵌入的散列函数的强度,则完全可以知道认证机制抗密码分析的强度。 前两个目标是HMAC 为人们所接受的重要原因。HMAC 把散列函数当成一个“黑盒”。 这有两个优点:第一,实现HMAC 时,现有的散列函数可以用作一个模块。这样,已经预 先封装的大量HMAC 代码可以不加修改地使用。第二,如果想替换一个HMAC 实现中的 特定散列函数,所需做的只是除去现有的散列函数模块,放入新模块。如果需要更快的散 列函数时就可以这样操作。更为重要的是,如果嵌入式散列函数的安全性受到威胁,可通 过简单地用更加安全的模块取代嵌入式散列函数,从而保证了HMAC 的安全。 实际上,上面列表中的最后一个目标是HMAC 相对其他散列方案最主要的优点。如果 能提供有一定合理性的抗密码分析强度的嵌入式散列函数,就能够证明HMAC 是安全的。 在本节后面再对此进行阐述,但首先分析HMAC 的结构。 HMAC 算法。图3.6 描述了HMAC 的整个操作。定义下列术语: 图3.6 HMAC 结构 H = 嵌入的散列函数(如SHA-1)。 M = 输入HMAC 的消息(包括嵌入式散列函数中特定的填充部分)。 Yi= M 的第i 个分组(0 i (L .1) ≤ ≤ )。 网络安全基础:应用与标准(第6 版) L = M 中的分组数。 b = 分组中的比特数。 n = 嵌入式散列函数产生的散列码长度。 K = 密钥;如果密钥长度大于b,则将其输入给散列函数生成n 比特的密钥;建议长度 大于或等于n。 K+ = 为使K 为b 位长而在K 左边填充0 后所得的结果。 ipad = 00110110 (十六进制数为36)重复b/8 次。 opad = 01011100 (十六进制数为5C)重复b/8 次。 那么HMAC 可用下式表示: HMAC(K,M)=H[(K+⊕opad)||H[(K+⊕ipad)||M]] 该算法描述如下: (1)在K 的左端追加0 构成b 比特的字符串K + (如K 的长度为160 比特,b=512,K 将被追加44 个0 字节)。 (2)ipad 与K + 进行XOR(按比特异或)生成b 比特的分组Si。 (3)将M 追加在S 上。 (4)将H 应用于骤(3)所产生的数据流 。 (5)opad 与K + 进行XOR 生成b 比特的分组So 。步(i) (6)将步骤(4)产生的散列结果追加在So 上。 (7)将H 应用于步骤6 产生的数据流,输出结果。 注意,与ipad 进行异或将导致K 一半的比特翻转。类似地,与opad 进行异或也导致K 一半的比特翻转,但翻转的比特却不同。实际上,用散列算法处理Si和So ,已经从K 伪随 机地生成了两个密钥。 HMAC 的执行时间应该与嵌入式散列函数处理长消息所用的时间近似相等。HMAC 多 执行了三次基本的散列函数(Si、So 和内部散列生成的数据块)。 3.3.2 基于分组密码的MAC 在这一章中将讨论几种基于分组密码的MAC。 基于密文的消息认证码(CMAC)。基于密文的消息认证码的操作模式适用于AES 和 3DES ,它在美国国家标准及技术研究所特刊(NIST Special Publication)800-38B 中被明确 规定了。 首先,当这个信息为一个长度为b 的密码块的整数倍数n 时,让我们考虑一个基于密 文的消息认证码的操作方式。在AES 中,b=128,在3DES 中,b=64,并且这个信息被分 为n 块(M1,M2,…,Mn)。这个运算方式利用了一个k 比特的加密密钥K 和n 比特的密钥, K1。在AES 中,密钥大小k 为128 、192 或者256 比特;在3DES 中,密钥大小为112 或者 168 比特。基于密文的消息认证码按照下面的步骤被计算出(见图3.7)。 C1=E (K, M1) C2=E (K, [M2⊕C1]) C3=E (K, [M3⊕C2]) 第3 章公钥密码和消息认证 # Cn =E (K,[Mn⊕Cn ―1⊕K1]) T=MSBTlen (Cn) 其中: T =信息认证码,或者称为标签; Tlen =T 的位长度; MSBs(X)=位串X 的最左边的s 比特二进制数。 如果这个信息不是一个密码块长度的整数倍数,那么将在最后一个块(最低有效位) 的右边填充由一位1 和若干位0 组成的位串,以使得最后一个块的长度也为b 比特。CMAC 操作与以前一样,只是它使用一个不同的n 比特密钥K2 取代K1。 图3.7 基于密文的消息认证码(CMAC) 为了生成两个n 比特的密钥,分组密码应用于一个全部由0 组成的块。通过对密文块 左移一比特并且根据块大小异或一个常数,可以获得一个子密钥。第二个子密钥的产生方 式与第一个子密钥的产生方式相同。 具有密码块链式信息认证码的计数器。CCM 的操作模式在NIST SP 800-38C 中定义, 又被称为认证加密模式。认证加密是一个被用来描述加密系统的专业术语,这个加密系统 同时确保了信息的机密性和可靠性(完整性)。许多应用和协议需要这两种形式的安全,但 是直到近期仍然单独设计这两种服务。 CCM 的核心算法是AES 加密算法(见2.2 节),CTR 操作模式(见2.5 节)和CMAC 认证算法。一个单独的密钥K 同时被加密和MAC 算法使用。CCM 加密数据处理的输入端 包含了3 个基本部分。 (1)能被认证和加密的数据。这是数据块的明文P。 (2)能被认证但是不能被加密的关联数据A。例如,为了确保协议操作正确,一个协议 网络安全基础:应用与标准(第6 版) 头只能未加密进行传输,但是需要被认证。 (3)指定了负荷量和相关联的数据的随机数N。这个特殊的值在每个例子中都不同, 并且被用来阻止重放攻击和其他类型的攻击。 图3.8 说明了CCM 的操作过程。在认证方面,输入包括了随机数、相关联的数据和明 文。这个输入数据按照B0 到Br 的序列格式。第一个块包含了随机数以及格式化的比特,这 些比特给出了N、A 和P 元素的长度。第一块后面紧跟着0 块或者更多的含有A 的块,之 后是0 块或者更多的含有P 的块。这些块的序列作为CMAC 算法的输入,能产生一个长度 为Tlen 的MAC 值,Tlen 小于或者等于块的长度(如图3.8(a)所示)。 图3.8 具有密码块链式信息认证码的计数器(CCM) 在加密中,计数器的值必须独立于随机数而产生。认证标签使用只有一个计数器Ctr0 的 CTR 模式加密。输出的Tlen 位最高有效位跟认证标签异或,从而产生加密标签。剩下的计 数器被用来在CTR 模式中加密明文(如图2.11 所示)。加密的明文和加密标签连接起来以 获得最后的密文输出。 3.4 公钥密码原理 公钥密码与传统密码同等重要,它还可以用来进行消息认证和密钥分发。本节首先考 虑公钥密码的基本概念,然后初步研究密钥的分发问题。3.5 节介绍两种最重要的公钥算法: 第3 章公钥密码和消息认证 RSA 和Diffie-Hellman。3.6 节介绍数字签名。 3.4.1 公钥密码思想 Diffie 和Hellman 在1976 年首次公开提出了公钥密码思想[DIFF76],这是有文字记载 的几千年来密码领域第一次真正革命性的进步。公钥算法基于数学函数,而不像对称加密 算法那样是基于比特模式的简单操作。更为重要的是公钥密码系统是非对称的,它使用两 个单独的密钥。与此相比,对称的传统密码只使用一个密钥。使用两个密钥对于保密性、 密钥分发和认证都产生了意义深远的影响。 在继续进行前,首先看看关于公钥密码的几种常见误解。第一种误解是,公钥密码比 传统密码更抗密码分析。实际上,任何加密方案的安全性取决于:(1)密钥长度; (2)攻破密码所需的计算量。从抗密码分析的角度来说,原则上不能说传统密码优于公钥 密码,也不能说公钥密码优于传统密码。第二种误解认为公钥密码是一种通用技术,传统 密码则过时了。相反,由于当前公钥密码方案的计算开销太大,传统密码被淘汰似乎不太 可能。最后一种误解认为,传统密码中与密钥分配中心的会话是很麻烦的事情,而用公钥 密码实现的密钥分配非常简单。事实上,公钥密码也需要某种形式的协议,该协议包含一 个中心代理。所以与传统密码相比,公钥密码所需的操作并不简单或者高效。 公钥密码方案由6 个部分组成(见图3.9(a): z 明文:算法的输入,它是可读的消息或数据。 z 加密算法:加密算法对明文进行各种形式的变换。 z 公钥和私钥:算法的输入,这对密钥如果一个密钥用于加密,则另一个密钥就用于 解密。加密算法所执行的具体变换取决于输入端提供的公钥或私钥。 z 密文:算法的输出,取决于明文和密钥。对于给定的消息,两个不同的密钥将产生 两个不同的密文。 z 解密算法:该算法接收密文和匹配的密钥,生成原始的明文。 顾名思义,密钥对中的公钥是公开供其他人使用的,而只有自己知道私钥。通常的公 钥密码算法根据一个密钥进行加密,根据另一个不同但相关的密钥进行解密 。 基本步骤如下 : (1)每个用户都生成一对密钥用来对消息进行加密和解密。 (2)每个用户把两个密钥中的一个放在公共寄存器或其他可访问的文件里,这个密钥 便是公钥,另一个密钥自己保存。如图3.7(a)所示,每个用户都收藏别人的公钥。 (3)如果Bob 希望给Alice 发送私人消息,则他用Alice 的公钥加密消息。 (4)当Alice 收到这条消息,她用私钥进行解密。因为只有Alice 知道她自己的私钥, 其他收到消息的人无法解密消息。 用这种方法,任何参与者都可以获得公钥。由于私钥由每一个参与者在本地产生,故 不需要分发。只要能够保护好他或她的私钥,以后的通信就会安全。在任何时候,用户都 能够改变私钥,且发布相应的公钥代替旧公钥。 传统密码算法中使用的密钥被特别地称为密钥。用于公钥密码的两个密钥被称为公钥和 私钥。私钥总是保密的,但仍然被称为私钥而不是密钥,这是为了避免与传统密码混淆。 网络安全基础:应用与标准(第6 版) 图3.9 公钥密码 3.4.2 公钥密码系统的应用 在进一步介绍公钥密码系统的应用前,需要对公钥密码系统有清楚的理解,否则容易 引起混淆。公钥系统的特征就是使用具有两个密钥的加密算法,其中一个密钥为私人所有, 另一个密钥是公共可用的。根据应用,发送方要么使用发送方的私钥,要么使用接收方的 公钥,或者两个都使用,从而实现某种类型的加密函数。在广义上可以把公钥密码系统分 为如下三类。 z 加密/解密:发送方用接收方的公钥加密消息。 z 数字签名:发送方用自己的私钥“签名”消息。签名可以通过对整条消息加密或者 对消息的一个小的数据块加密来产生,其中该小数据块是整条消息的函数。 z 密钥交换:通信双方交换会话密钥。这可以使用几种不同的方法,且需要用到通信 一方或双方的私钥。 有些算法可用于上述三种应用,而其他一些算法仅适用于这些应用中的一种或两种。 第3 章公钥密码和消息认证 表3.2 列出了本章讨论的算法(RSA 和Diffie-Hellman )所支持的应用。该表还包括了本章 后面将会提到的数字签名标准(DSS)和椭圆曲线密码。 这里可以得出一个一般规律。即相对于同样的安全性要求和同样的密文长度,与对称 密码算法相比,公钥密码算法需要更多计算。正因如此,公钥密码算法仅用于加密短的消 息或数据块,如加密一个秘密密钥或PIN 码。 表3.2 公钥密码系统的应用 算 法 加密/解密 数 字 签 名 密 钥 交 换 RSA 是是是 Diffie-Hellman 否否是 DSS 否是否 椭圆曲线是是是 3.4.3 公钥密码的要求 图3.9 所示的密码系统建立在两个相关联密钥的密码算法之上。Diffie 和Hellman 假设 了这个系统是存在的,但是并没有证明这种算法的存在性。然而,他们给出了这些算法必 须满足的条件[DIFF76] : (1)接收方B 计算生成密钥对(公钥PU 、私钥PR)是容易的。(2)已知公钥和需要加密的消息M时,发(b) 送方A 容计算生成相应的密文 : = ( b,易(b) CEPU M ) (3)接收方B 用私钥解密密文时,比较容易通过计算恢复原始消息 : M= ( ,) = DP[ b,( UM ) ] DPb REP, RC b (4)当攻击者已知公钥PU 时,不可能通过计算推算出私钥PR。 (5)攻击者在已知公钥P。 还可以加上第6 个要求。管有用,但是这对于所有的公钥应用并不是必须的。U和密文C的情况下,通过计算不可能(b) 恢复原始消息M(b) 尽(b) (6)两个相关密钥中的任何一个都可以用于加密,另一个密钥用于解密 。 [ U EP,( b, )] = DP[ ,( U M b, ) ] M= DPb RM REPb 3.5 公钥密码算法 RSA 和Diffie-Hellman 是使用最广泛的两种公钥算法。本节分析这两种算法,然后简要 介绍另外两种算法1。 3.5.1 RSA 公钥密码算法 最初的公钥方案是在1977 年由Ron Rivest 、Adi Shamir 和Len Adleman 在MIT 提出的, 本节使用一些数论的基本概念。请参考附录A。 网络安全基础:应用与标准(第6 版) 并且于1978 年首次发表[RIVE78]。RSA 方案从那时起便占据了绝对的统治地位,成为最广 泛接受和实现的通用公钥加密方法。RSA 是分组密码,对于某个n,它的明文和密文是0~n.1 之间的整数。 基本的RSA 加解密对于某一明文块M和密文块C,加密和解密有如下的形式: CM= emod n mod n= (M) mod nM mod M= Cd ed = ed n 发送方和接收方都必须知道n和e的值,并且只有接收方知道d的值。RSA 公钥密码 算法的公钥KU= {, }n,私钥 = dn eKR {,}。为使该算法能够用于公钥加密,它必须满足下 列要求: (1)可以找到e、d、n的值,使得对所有的M, Medmod =