author : Odyssey@cyberpeace
消息认证的目标是:收到一条消息,希望确保消息在传递的过程中没有被改变
这不一定包括对消息进行加密或签名
第1章曾介绍过信息安全所面临的基本攻击类型,包括被动攻击(获取消息的内容、业务流分析)和主动攻击(假冒、重放、消息的篡改、业务拒绝)。抗击被动攻击的方法是前面已介绍过的加密,本章介绍的消息认证则是用来抗击主动攻击的。消息认证是一个过程,用以验证接收消息的真实性(的确是由它所声称的实体发来的)和完整性(未被篡改、插入、删除),同时还用于验证消息的顺序性和时间性(未重排、重放、延迟)。除此之外,在考虑信息安全时还需考虑业务的不可否认性,即防止通信双方中的某一方对所传输消息的否认。实现消息的不可否认性可通过数字签字,数字签字也是一种认证技术,它也可用于抗击主动攻击。”
可能的消息认证攻击:
消息认证机制和数字签字机制都需有产生认证符的基本功能,这一基本功能又作为认证协议的一个组成部分。认证符是用于认证消息的数值,它的产生方法又分为消息认证码MAC(message authentication code)和哈希函数(hash function)两大类
消息认证码是指消息被一密钥控制的公开函数作用后产生的、用作认证符的、固定长度的数值,也称为密码校验和。此时需要通信双方A和B共享一密钥K。设A欲发送给B的消息是M,A首先计算$MAC=C_K(M)$,其中C_K(·)是密钥控制的公开函数,然后向B发送M‖MAC,B收到后做与A相同的计算,求得一新MAC,并与收到的MAC做比较,如图5.1(a)所示。
如果仅收发双方知道K,且B计算得到的MAC与接收到的MAC一致,则这一系统就实现了以下功能:
AC函数与加密算法类似,不同之处为MAC函数不必是可逆的,因此与加密算法相比更不易被攻破。 上述过程中,由于消息本身在发送过程中是明文形式,所以这一过程只提供认证性而未提供保密性。为提供保密性可在MAC函数以后(如图5.1(b))或以前(如图5.1(c))进行一次加密,而且加密密钥也需被收发双方共享。在图5.1(b)中,M与MAC链接后再被整体加密,在图5.1(c)中,M先被加密再与MAC链接后发送。通常希望直接对明文进行认证,因此图5.1(b)所示的使用方式更为常用。
使用加密算法(单钥算法或公钥算法)加密消息时,其安全性一般取决于密钥的长度。如果加密算法没有弱点,则敌手只能使用穷搜索攻击以测试所有可能的密钥。如果密钥长为k比特,则穷搜索攻击平均将进行$2^{k-1}$个测试。特别地,对惟密文攻击来说,敌手如果知道密文C,则将对所有可能的密钥值$K_i$执行解密运算$P_i=D_{Ki}(C)$,直到得到有意义的明文。
对MAC来说,由于产生MAC的函数一般都为多到一映射,如果产生n比特长的MAC,则函数的取值范围即为$2^n$个可能的MAC,函数输入的可能的消息个数N»2n,而且如果函数所用的密钥为k比特,则可能的密钥个数为$2^k$。如果系统不考虑保密性,即敌手能获取明文消息和相应的MAC,那么在这种情况下要考虑敌手使用穷搜索攻击来获取产生MAC的函数所使用的密钥。
假定k>n,且敌手已得到$M_1$和$MAC_1$,其中$AC_1=C_{K1}(M_1)$,敌手对所有可能的密钥值$K_i$求$MAC_i=C_{Ki}(M_1)$,直到找到某个$K_i$使得$MAC_i=MAC_1$。由于不同的密钥个数为$2^k$,因此将产生$2^k$个MAC,但其中仅有$2^n$个不同,由于$2^k>2^n$,所以有很多密钥(平均有$2^k/2^n=2^{k-n}$个)都可产生出正确的$MAC_1$,而敌手无法知道进行通信的两个用户用的是哪一个密钥,还必须按以下方式重复上述攻击:
第1轮 已知$M_1$、$MAC_1$,其中$MAC_1=C_K(M_1)$。对所有$2^k$个可能的密钥计算$MAC_i=C_{Ki}(M_1)$,得$2^{k-n}$个可能的密钥。 第2轮 已知$M_2$、$MAC_2$,其中$MAC_2=C_K(M_2)$。对上一轮得到的$2^{k-n}$个可能的密钥计算$MAC_i=C_{Ki}(M_2)$,得$2^{k-2×n}$个可能的密钥。 如此下去,如果$k=αn$,则上述攻击方式平均需要$α$轮。例如,密钥长为80比特,MAC长为32比特,则第1轮将产生大约248个可能密钥,第2轮将产生216个可能的密钥,第3轮即可找出正确的密钥。
如果密钥长度小于MAC的长度,则第1轮就有可能找出正确的密钥,也有可能找出多个可能的密钥,如果是后者,则仍需执行第2轮搜索。 所以对消息认证码的穷搜索攻击比对使用相同长度密钥的加密算法的穷搜索攻击的代价还要大。然而有些攻击法却不需要寻找产生MAC所使用的密钥。
例如,设M=(X1‖X2‖…‖Xm)是由64比特长的分组$X_i(i=1,…,m)$链接得到的,其消息认证码由以下方式得到: $\varDelta (M)=X_1\oplus X_2\oplus …\oplus X_m$ $C_K(M)=E_K[\varDelta(M)]$ 其中$\oplus$表示异或运算,加密算法是电码本模式的DES。因此,密钥长为56比特,MAC长为64比特,如果敌手得到M‖CK(M),那么敌手使用穷搜索攻击寻找K将需做256次加密。然而敌手还可用以下方式攻击系统: 将$X_1$到$X_{m-1}$分别用自己选取的$Y_1$到$Y_{m-1}$替换,求出$Ym=Y_1\oplus Y_2\oplus …\oplus Y_{m-1}\oplus Δ(M)$,并用$Y_m$替换$X_m$。因此敌手可成功伪造一新消息$M’=Y_1…Y_m$,且M’的MAC与原消息M的MAC相同。
考虑到MAC所存在的以上攻击类型,可知它应满足以下要求,其中假定敌手知道函数C,但不知道密钥K: ① 如果敌手得到M和CK(M),则构造一满足CK(M′)=CK(M)的新消息M′在计算上是不可行的。 ② CK(M)在以下意义下是均匀分布的: 随机选取两个消息M、M′,Pr[CK(M)=CK(M′)]=2-n,其中n为MAC的长。 ③ 若M′是M的某个变换,即M′=f(M),例如f为插入一个或多个比特,那么Pr[CK(M)=CK(M′)]= 2-n。
第1个要求是针对上例中的攻击类型的,此要求是说敌手不需要找出密钥K而伪造一个与截获的MAC相匹配的新消息在计算上是不可行的。第2个要求是说敌手如果截获一个MAC,则伪造一个相匹配的消息的概率为最小。最后一个要求是说函数C不应在消息的某个部分或某些比特弱于其他部分或其他比特,否则敌手获得M和MAC后就有可能修改M中弱的部分,从而伪造出一个与原MAC相匹配的新消息。
数据认证算法是最为广泛使用的消息认证码中的一个,已作为FIPS Publication(FIPS PUB 113)并被ANSI作为X9.17标准。 算法基于CBC模式的DES算法,其初始向量取为零向量。需被认证的数据(消息、记录、文件或程序)被分为64比特长的分组D1,D2,…,DN,其中最后一个分组不够64比特的话,可在其右边填充一些0,然后按以下过程计算数据认证码(见图6.2):
数据认证算法
其中E为DES加密算法,K为密钥。
数据认证码或者取为$O_N$或者取为$O_N$的最左M个比特,其中16≤M≤64。
Hash函数是一个将任意长度的消息(message)映射成固定长度消息的函数。
将h称为一个Hash函数(hash function),或称为哈希函数、散列函数。对于任何消息x ,将h(x)称为x的Hash值、散列值、消息摘要(message digest)。
设x、x’是两个不同的消息,如果
h(x)=h(x’)
则称x和x’是Hash函数h的一个(对)碰撞.
$(1-\frac{1}{365})(1-\frac{2}{365}…(1-\frac{k-1}{365})$
k人中至少有2人生日相同的概率为:
$p(365,k)=1-(1-\frac{1}{365})(1-\frac{2}{365}…(1-\frac{k-1}{365})$
有P(365,23)=0.5073。即在23个人中,至少有两个人生日相同的概率大于0.5,这个数字比人们直观猜测的结果小得多,因而称为生日悖论。
生日攻击法
生日悖论原理可以用于构造对Hash函数的攻击
设Hash函数值有n个比特,m是真消息,M是伪造的假消息,分别把消息m和M表示成r和R个变形的消息。消息与其变形消息具有不同的形式,但有相同的含义。将消息表示成变形消息的方法很多,例如增加空格、使用缩写、使用意义相同的单词、去掉不必要的单词等。
生日攻击法
分别把消息m和M表示成r和R个变形的消息
计算真消息m的变形与假消息M的变形发生碰撞的概率 由于n比特长的散列值共有2n个,所以对于给定m的变形mi和M的变形Mj,mi与Mj不碰撞的概率是1-1/2n。由于M共有R个变形,所以M的全部变形都不与mi碰撞的概率是:
$(1-\frac{1}{2^n})^R$
因为消息m共有r个变形,因此m的变形与M的变形都不碰撞的概 率是:
$(1-\frac{1}{2^n})^{rR}$
m的变形与M的变形发生碰撞的概率是:
$P(n)=1-(1-\frac{1}{2^n})^{rR}\approx1-e^{-\frac{rR}{2^n}}$
当r=R=2n/2时,P(n)=1e10.63。对于Hash值长度为64比特的Hash函数,生日攻击的时间复杂度约为232,所以是不安全的。
为了抵抗生日攻击,建议Hash值长度至少为128 比特
中间相遇攻击(in-the-middle attack)
设加密体制为: $H=M=\sum^n,E_k:H\times M$ →$\sum^n$
对于消息m=(m1, m2),其散列值的计算分以下两步: (1) h1= EK(m1, IV); (2) d=h(m)=EK (m2, h1), 其中IV是加密变换的初始值。 这类Hash函数将遭受中间相遇攻击。
令:${M_{1,i} | i=1,2,…,r},{M_{2,j}=1,2,…,R}$ |
计算:$H_1={h_{1,i}=E_K(M_{1,i},IV) | i=1,2,…,r}$ |
$H_2={h_{2,j}=D_K(M_{2,j}),d | j=1,2,…,R}$ |
这里DK是解密变换。假设加密变换EK是随机的,那么可以使用生日攻击法来分析集合H1和H2中出现相同元素的概率。 如果集合H1与H2有相同元素,例如h1, i= h2, j=DK(M2, j, d),则有d=EK (M2, j, h1,i ),即M与m有相同的散列值d。
$h_1=E_k(m_1,IV)$
$d=h(m)=E_k(m_2,h_1)$
压缩函数(compression function)
$f:{0,1}^{m+t}$ →${0,1}^m\space (t\geq 1)$
迭代技术 设x是一个长度为L的比特串。重复应用压缩函数f,对消息x进行多次压缩,最后得到x的散列值
计算消息x的散列值h(x)的步骤
$y=x | pad(x)=y_1 | y_2 | … | y_r$ |
其中| yi|=t (i =1, 2,…, r),pad(x)称为填充函数。典型的填充函数是先添加x长度| x|的值,再添加若干比特(例如0)。
$Hi= f (H_{i-1} | y_i) (i=1, 2,…,r)$ |
$h(x)=g(H_r)$
MD5(MD:message digest,消息摘要) 1990年10月, 著名密码学家R. L. Rivest在MIT(Massachusetts Institute of Technology)提出了一种Hash函数,作为RFC 1320 (RFC:互联网研究和开发机构工作记录)公开发表,称为MD4. MD5是MD4的改进版本, 于1992年4月作为RFC 1321公开发表.
MD5算法的输入可以是任意长度的消息x,对输入消息按512位的分组为单位进行处理,输出128位的散列值MD(x)。整个算法分为五个步骤。
步骤1: 增加填充位
步骤2: 附加消息长度值 用64位表示原始消息x的长度,并将其附加在步骤1所得结果之。若填充前消息长度大于264,则只使用其低64位。填充方法是把64比特的长度分成两个32比特的字,低32比特字先填充,高32比特字后填充。
步骤1与步骤2一起称为消息的预处理
假设消息为: x=“abcde”=01100001 01100010 01100011 01100100 01100101=$(61 62 63 64 65)_{16}$,|x|=40=$(28)_16$
在x的右边填充1个“1”和407个“0”,将x变成448比特的$x_1$:
$x_1$= $x$ || 1 || 0 (407个) = $x$ || 800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 =61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
$x$=“abcde”=01100001 01100010 01100011 01100100 01100101=(61 62 63 64 65)16, | x | =40=(28)16 |
处理后的比特串为(16进制表示): $x_2=x_1||28$(64位) =61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 28000000 00000000
步骤3:初始化MD缓冲区
A=67 45 23 01 B=EF CD AB 89 C=98 BA DC FE D=10 32 54 76
字A=01 23 45 67 字B=89 AB CD EF 字C=FE DC BA 98 字D=76 54 32 10
步骤4:压缩函数
以512位的分组(16个字)为单位处理消息
$H_{MD5}:{0,1}^{128+512}$ → ${0,1}^{128}$
步骤4是MD5算法的主循环,它以512比特作为分组,重复应用压缩函数$H_MD5$,从消息Y的第一个分组$Y_1$开始,依次对每个分组$Y_i$进行压缩,直至最后分组$Y_{L-1}$,然后输出消息x的Hash值。可见,MD5的循环次数等于消息Y中512比特分组的数目L。
MD5压缩函数$H_{MD5}$
$H_{MD5}:{0,1}^{128+512}$ → ${0,1}^{128}$
$H_{MD5}$的四轮处理过程的算法结构相同,每一轮要对缓冲区ABCD进行16次迭代,每次迭代的运算形式为:
$a←b+L^s(a+g(b,c,d)+X[k]+T[i])$
其中a、b、c、d分别为缓冲区A、B、C、D中的字,运算结束后再将(a、b、c、d)循环右移一个字。
轮数 | 基本逻辑函数g | g(b,c,d) |
---|---|---|
1 | F(b,c,d) | $(b\wedge c)\vee (\overline b \wedge d)$ |
2 | G(b,c,d) | $(b\wedge d)\vee (c \wedge \overline d)$ |
3 | H(b,c,d) | $b\oplus c\oplus d$ |
4 | I(b,c,d) | $c\oplus (b\wedge \overline d)$ |
$H_MD5$的基本逻辑函数g 基本逻辑函数g的真值表
在每一轮的16步迭代中, 每一步迭代使用一个字,迭代步数不同使用的字也不相同. 因此, 16步迭代恰好用完16个字。
例如:第三轮处理过程的第i步迭代使用字 $X[\rho_3(i)]=X[(5+3_i)\space mod\space 16]$ 第8步迭代使用字 $X[\rho_3(8)]=X[(5+3\times 8)]=X[29]=X[23]$
循环左移位数s $L^s(v)$表示对32位的变量v循环左移s位。s的值与轮数和迭代步数有关。
步数 \ 轮数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 7 | 12 | 17 | 22 | 7 | 12 | 17 | 22 | 7 | 12 | 17 | 22 | 7 | 12 | 17 | 22 |
2 | 5 | 9 | 14 | 20 | 5 | 9 | 14 | 20 | 5 | 9 | 14 | 20 | 5 | 9 | 14 | 20 |
3 | 4 | 11 | 16 | 23 | 4 | 11 | 16 | 23 | 4 | 11 | 16 | 23 | 4 | 11 | 16 | 23 |
4 | 6 | 10 | 15 | 21 | 6 | 10 | 15 | 21 | 6 | 10 | 15 | 21 | 6 | 10 | 15 | 21 |
步骤5: 输出 依次对消息的L个512比特的分组进行处理,第L个分组处理后的输出值即是消息x的散列值MD(x)。 可将MD5的处理过程归纳如下:
安全Hash算法SHA(secure hash algorithm)由美国标准与技术研究所(NIST)设计并于1993年作为联邦信息处理标准(FIPS 180)发布 修改版于1995年发布(FIPS 180-1),通常称之为SHA-1。该标准称为安全Hash函数。 RFC 3174也给出了SHA-1,它基本上是复制FIPS 180-1的内容,但增加了C代码实现。 SHA-1算法的输入是长度小于264的任意消息x,输出160位的散列值。
SHA-1处理消息的过程与MD5类似,对输入消息按512位的分组为单位进行处理,整个算法分为五个步骤
步骤1: 增加填充位
在消息右边增加若干比特,使其长度与448模512同余。即使消息本身已经满足上述长度要求,仍然需要进行填充。填充位数在1到512之间。填充比特的第一位是“1”,其它均为“0”。
步骤2: 附加消息长度值
用64位表示原始消息x的长度,并将其附加在步骤1所得结果之后。
经预处理后,原消息长度变为512的倍数。设原消息x经预处理后变为消息$Y=Y_0 Y1… Y_{L-1}$,其中$Y_i(i =0,1,…,L-1)$是512比特。在后面的步骤中,将对512比特的分组$Y_i$进行处理。
步骤3: 初始化缓冲区
SHA-1算法的中间结果和最终结果保存在160位的缓冲区里,缓冲区用5个32位的寄存器表示。5个缓冲区记为A、B、C、D、E,其初始值为下列32位整数(16进制表示):
A=67 45 23 01 B=EF CD AB 89 C=98 BA DC FE D=10 32 54 76 E=C3 D2 E1 F0
其中,前4个初始值与MD5的初始值相同。SHA1以大端格式存储缓冲区的值,即字的最高有效字节存于低地址字节位置。因此,上述初始值存储为(十六进制):
字A=67 45 23 01 字B=EF CD AB 89 字C=98 BA DC FE 字D=10 32 54 76 字E=C3 D2 E1 F0
$H_{SHA}:{0,1}^{160+512}→{0,1}^{160}$
SHA-1的压缩函数$H_{SHA}$
$A,B,C,D,E\space ←\space (E+f(B,C,D)+L^5(A)+W_t+K_t),A,L^{30}(B),C,D$
其中A、B、C、D、E分别为五个缓冲区中的字,运算结束后再将(A、B、C、D、E)循环右移一个字。
轮数 | 基本逻辑函数f | f(B,C,D) |
---|---|---|
1 | $f_1(B,C,D)$ | $(B\wedge C)\vee (\overline B \wedge D)$ |
2 | $f_2(B,C,D)$ | $B\oplus C \oplus D$ |
3 | $f_3(B,C,D)$ | $(B\wedge C)\vee (B \wedge D)\vee (C\wedge D)$ |
4 | $f_4(B,C,D)$ | $B\oplus C \oplus D$ |
$W_t=L^1(W_{t-16}\oplus W_{t-14}\oplus W_{t-3})\space (t=16,17,…79)$
加法常数表$K_t$
迭代步数 | 十六进制 | 十进制 |
---|---|---|
$0\leq t \leq 19$ | 5A827999 | [$2^{30}\times \sqrt{2}$] |
$20\leq t \leq 39$ | 6ED9EBA1 | [$2^{30}\times \sqrt{3}$] |
$40\leq t \leq 59$ | 8F1BBCDC | [$2^{30}\times \sqrt{5}$] |
$60\leq t \leq 79$ | CA62C1D6 | [$2^{30}\times \sqrt{10}$] |
步骤5: 输出
Hash函数的间接构造法
已知条件
设$E_k$是一个分组长度为n的分组密码的加密算法,密钥为k,对于任意的消息x,首先对x进行分组,每组的长度为n。设消息x为: $x=x_1 x_2…x_L$, 其中$x_i\in GF(2)^n\space (1\leq i\leq L)$
基于分组密码CBC工作模式构造Hash函数 首先选取一个初始值: $y_0=IV\in GF(2)^n$, 然后依次计算: $y_i=E_k(x_i\oplus y_{i-1})(1\leq i\leq L)$ 最后定义Hash值为: $h_{CBC}(x)=y_L$
基于分组密码CFB工作模式构造Hash函数
在密钥公开的情况下,基于分组密码CBC工作模式和CFB工作模式构造的Hash函数是不安全的,它们甚至不是弱无碰撞的.
Chaum-Heijst-Pfitzmann Hash函数是强抗碰撞的,用反证法,如果Hash函数h有一对碰撞,那么可以证明离散对数$log^{\alpha}\beta$能被有效计算.
设$(x_1, x_2)$,$(x_3, x_4)$是h的一对碰撞消息,即$(x_1, x_2)\neq (x_3, x_4)$,$h(x_1, x_2)=h(x_3, x_4)$,那么 $\alpha^{x_1}\beta^{x_2}=\alpha^{x_3}\beta^{x_4}\space mod\space p \space \Rightarrow\space \alpha^{x_1-x_3}=\beta^{x_4-x_2}\space mod\space p$
记$d=gcd(x_4-x_2, p-1)$。因为p-1=2q,且q是一个素数,所以$d\in {1,2, q, p-1}$。下面对d的四个取值分别进行讨论。
情况1:d =1
此时$x_4-x_2$关于模p-1有逆,设$y=(x_4-x_2)^{-1}\space mod\space(p-1)$,则存在整数k,使得$(x_4-x_2)y=1+(p-1)k$,则有
因此,可计算离散对数
情况2:d =2 因为$p-1=2q$,且q是奇数,所以$gcd(x_4-x_2, q)=1$。设$y=(x_4-x_2)^{-1}\space mod\space q$,则存在整数k,使得 $(x_4-x_2) y=1+qk$, 有
由于$\alpha^q=-1\space mod\space p$,所以
容易检验二式中哪一个成立. 即离散对数$log_{\alpha}^{\beta}$能被有效计算。
情况3:d = q 因为 0≤x2≤q-1, 0≤x4≤q-1 $\rightarrow -(q-1)≤x4-x2≤q-1 \rightarrow gcd(x4-x2, q-1)= q$不成立。 情况3不存在.
情况4:d =p-1 这种情况只有在$x_2=x_4$时才可能发生。这样就有 $\alpha^{x-1}=\alpha^{x_3}\space mod\space p$ 所以$x_1=x_3,(x_1, x_2)= (x_3, x_4)$,与已知矛盾! 即情况4也不存在。