(七)带密钥的哈希

带密钥的哈希

消息认证码(MAC)

消息认证码通过创建一个标签T=MAC(K,M)来保护消息的完整性和真实性(K是密钥,M是消息),这个标签被称为消息M的认证标签(也称为消息M的消息认证码)。只要知道消息认证码的密钥就可以验证消息是否被修改。

注意:消息认证码不能抵御允许重放标签的攻击,为了防止此类重放攻击,解决办法是协议在每个消息中包含一个消息编号。这个编号随着新消息的增多而递增(或者永远不会重复),消息接收者应该记录已经接收的编号,并验证当前编号是否已经接收。

伪随机函数(PRF)

伪随机函数(PRF)是一个使用密钥K来返回PRF(K,M)的函数,函数的输出看起来是随机的。PRF一般不单独使用,而是作为密码算法或协议的一部分。

在不知道密钥K的前提下,没有办法将伪随机函数的输出值与真正的随机值区分开来。

构建带密钥的哈希

加秘密前缀的方法

该方法通过对消息级联(两者拼在一起,例如12和34级联就是1234)一个密钥K并返回Hash(K || M)来实现将普通的哈希函数转化为一个带密钥的哈希。

在两种情形下这种方法并不安全,一种情况是当哈希函数容易遭受长度扩展攻击时,另一种情形是哈希支持不同长度的密钥时。

注:长度扩展攻击允许攻击者在既不知道M1又不知道K的情况下,仅仅由Hash(K||M1)就可以计算哈希值Hash(K||M1||M2)。

加秘密后缀的方法

加秘密后缀的方法是将密钥放在消息后面进行哈希,它通过Hash(M || K)来生成一个PRF

把密钥放在后面后,长度扩展攻击不会对此种方法奏效。因为攻击需要从Hash(M1 || K)得到Hash(M1 || K || M2),而Hash(M1 || K || M2)并不是一个有效的加秘密后缀的MAC。

HMAC

基于哈希的MAC(HMAC)的构造方法能从一个哈希函数构造一个MAC,这种构造方法比上面两种方法更安全。

HMAC计算过程如下图

公式为:

Hash((K ⊕ opad) || Hash((K ⊕ ipad) || M)) 

opad(外填充)是一个字符串(5c5c5c…5c),和函数Hash的分组长度相同。密钥K通常比分组长度短,将它用全0填充至分组长度,然后和opad相异或。

ipad(内填充)是一个字符串(363636…36),也和函数Hash的分组长度相同。同样,如果密钥K比分组长度短,就将K用全0填充至分组长度,然后和ipad相异或。

如果Hash函数采用SHA-256,则称它的HMAC实例为HMAC-SHA-256。一般称HMAC-Hash为一个使用Hash函数的HMAC实例。

CMAC 

意思为基于密码的MAC,它只提供一个分组密码来构造MAC,使用基于分组密码的CBC模式进行工作。

CBC-MAC

CBC-MAC是最早的CMAC,它给定一个分组密码E来计算一个消息M的标签。

CBC-MAC用CBC模式对全0初始值IV下的消息M进行加密,并且只保留最后一组密文作为消息M的标签。即分别计算C1=E(K,M1)、C2=E(K,M2⊕C1)、C3=E(K,M3⊕C2),......保证对M的每个分组只保留最后的Ci——这就是经过CBC-MAC的M的标签。

这样做是不安全的,假设现在有消息M1,M2,分组长度相同,T1=E(K,M1)和T2=E(K,M2)是它们对应的标签,现在有(M1,T1)和(M2,T2)两组数据,

假设有消息M0=M1 || (M2 T1)  (||代表级联,分组1是M1,分组2是(M2 ⊕ T1))

CBC模式下:

先计算C1=E(K,M1)=T1

再计算C2=E(K,(M2 ⊕ T1)⊕ T1)=E(K,M2)=T2

可以看出M0和M2的标签都是T2,这说明攻击者可以伪造CBC-MAC的标签。

CMAC

CBC-MAC在生成标签的过程中,每组密文使用的密钥都相同,而CMAC使用两个不同的密钥,它通过在生成最后一组密文时使用不同的密钥来修改CBC-MAC。CMAC首先从主密钥K中生成两个密钥K1和K2(保证K、K1和K2两两不同)。在CMAC中,最后一组密文由K1或K2加密产生,而之前的密文全是由主密钥K加密得到的。

为了计算K1和K2,CMAC首先计算一个临时值L=E(0,K)这里0是分组密码中对应密钥的输入值,而K是对应明文分组的输入值若L的最高比特位(MSB)是0,那么CMAC中令K1 =(L<<1);若L的MSB是1,那么令K1 =(L<<1)⊕87。(数字87是根据分组长度128比特的数学属性而精心挑选的,如果分组长度不是128比特,那么数字就不是87了)如果K1的MSB是0,那么就令K2=(K1<<1);否则令K2=(K1<<1)⊕87。

给定K1和K2,除了最后一个分组之外,CMAC的工作原理和CBC-MAC一样。

1.如果最后一个消息Mn的长度恰好等于分组长度,那么CMAC返回E(K,Mn⊕C(n-1)⊕K1)作为标签。

2.如果Mn的长度小于分组长度,CMAC会用100...0来填充Mn至分组长度,然后返回E(K,Mn⊕C(n-1)⊕K2)作为标签。

注意,第一种情况仅使用K1而第二种情况仅使用K2,但是两种情况在处理最后一个分组之前都是使用主密钥K来加密的。

消息是完整分组序列的情形
消息的最后一个分组必须填充的情形

与CBC加密模式不同,CMAC不需要设置参数IV,它是确定的:对于给定的消息M,CMAC始终返回相同的标签,因为计算CMAC(M)不是随机的,MAC不需要随机性来保证安全性。

poly1305

通用哈希函数

Poly1305 MAC的内部使用了一个通用哈希函数,通用哈希函数比密码学中的哈希函数要弱得多,不过速度更快。

给定一个消息M和密钥K,记UH(K,M)为一个通用哈希函数经M和K计算的输出。

通用哈希函数只有一个安全要求:对于任意两个消息M1和M2,对于一个随机密钥K来说,UH(K,M1)=UH(K,M2)的概率是可以忽略不计的。与PRF不同,通用哈希不需要是伪随机的;通用哈希非常简单,只需要满足对于许多不同的密钥,没有消息对(M1,M2)的哈希值相同即可。

可以把一个通用哈希作为MAC来验证消息,但只能验证一个消息。

例如,考虑在Poly1305中使用的通用哈希,它被称为多项式计算哈希。多项式计算哈希包含一个素数参数p,与前面提到的哈希有两个输入K和M不同,多项式计算哈希的输入是由两个范围在[1,p]的数构成的密钥,这两个数分别是R和K。设消息M由n个分组(M1,M2,...,Mn)构成,那么计算通用哈希的输出如下:

UH(R,K,M) = R + (M1)*K + (M2)*(K^2) + (M3)*(K^3) + ... + (Mn)*(K^n) mod p

一般基于通用哈希的MAC通常处理长度为128比特的消息分组,使用的素数p略大于2^128,比如为2^128+51。128比特的宽度可通过高效使用普通CPU的32位和64位算术单元来非常快地实现。

通用哈希有一个缺点:一个通用哈希只能安全地验证一个消息。攻击者可以通过只请求两个消息的标签来攻击前述的多项式计算MAC。例如,攻击者可以对满足M1=M2=...=0的消息请求消息的标签。因为UH(R,K,0)=R。或者,攻击者也可以对满足M1=1和M2=M3=...=0的消息请求标签,这样的消息的标签为T=R+K,从T中减去R就可以找到K。现在,攻击者知道了整个密钥(R,K),可以对任何消息伪造MAC。

Wegman-Carter MAC

Wegman-Carter构造:使用通用哈希函数可以对多个消息进行身份验证

它是用一个通用哈希函数和一个PRF来构建一个MAC,Wegman-Carter构造使用了两个密钥K1和K2:

MAC(K1,K2,N,M) = UH(K1,M) + PRF(K2,N)

其中N是一个nonce,而且对于每个密钥K2应该是唯一的,而PRF的输出规模与通用哈希函数UH的输出相同。通过添加这两个值,PRF输出的强伪随机性掩盖了UH的密码上的弱点。可以将其看作对通用哈希结果的加密,其中PRF充当了序列密码的角色,这样可以实现使用同一个密钥(K1)对多个消息进行身份验证。

Wegman-Carter构造方法在如下假设下可以给出一个安全的MAC:

1. UH是安全的通用哈希。

2. PRF是安全的PRF。

3. nonce N对每个密钥K2只使用一次。

4. UH和PRF的输出足够长。

 Poly1305

Poly1305 结合了 Poly1305通用哈希和分组密码 AES,因此最初提出时被称为Poly1305-AES。Poly1305-AES比HMAC、CMAC都要快得多,它只计算一个AES分组,并通过一系列简单的算术运算来并行处理消息。

现在给定128比特的K1、K2、N,和消息M,Poly1305-AES的返回值如下:

Poly1305(K1,M) + AES(K2,N) mod 2^128     (模2^128运算确保结果仍然是128比特

其中

Poly1305(K1,M) = (M1)*(K1)^n + (M2)*(K1)^(n-1) + ... + (Mn)*(K1) mod 2^130 - 5

计算过程:

1.M被拆成128比特的分组序列(M1,M2,...,Mn),并且对每个分组添加一个比特1(放在最高位),现在所有分组的长度都为129比特。(如果最后一个分组小于16字节,则先把这个消息分组用0填充至128比特,然后在最高位添加1构成129比特。)

2.计算Poly1305(K1,M),结果是一个最多129比特的整数。

3.和AES(K2,N)(128比特)相加,经过模2^128运算后成为一个128比特的MAC。

Poly1305-AES的安全分析表明,只要AES是安全的,那么Poly1305-AES就能提供128比特的安全性。

SipHash

SipHash是为了解决哈希表的拒绝服务攻击而设计的。

由于哈希表处理的大多是短输入,所以SipHash针对短消息进行了优化。

下面为siphash的工作原理图。

SipHash的128比特密钥被看作两个64比特的字,K1和K2,SipHash的256比特的内部状态被看作4个64比特的字。

SipHash在与消息分组置换前和置换后各异或一次,

1.密钥和内部状态相异或,之后丢弃密钥。

2.接着通过SipRound函数进行迭代。

3.将结果和消息分组相异或,用来修改SipHash的内部状态。

4.最后将内部状态的4个64比特的字相异或得到一个64比特的标签。

SipRound函数使用异或、加法和字的循环移位来保证函数的安全。SipRound通过执行下面从上到下的操作,将4个64比特的字(a,b,c,d)转换成一个状态。

左边和右边的操作是独立的,因此可以并行执行。

操作

a +=b               c+= d

b<<<=13          d<<<=16

b =a              d = c

a<<= 32   

c+=b               a += d
b <<< =17        d<<<= 21
b =c              d =a
c <<<=32

SipHash不同的版本记为SipHash-x-y,这表明它对每个消息分组之间进行x轮SipRound操作,然后进行y轮SipRound操作。默认的版本是SipHash-2-4(简写为SipHash,上图中就是)。如果想更安全也可以使用SipHash-4-8,不过它的运算时间是SipHash-2-4的两倍。

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值