一种生成消息认证码的方法
技术领域
本发明涉及密钥算法领域,具体说是一种使用密钥生成设备生成消息认证码的方法。
背景技术
在现有信息加密技术中,常见的信息保护手段大致可以分为保密和认证两大类。目前的认证技术有对用户的认证和对消息的认证两种方式,用户认证用于鉴别用户的身份是否是合法用户;消息认证就是验证所收到的消息确实是来自真正的发送方且未被修改的消息,也可以验证消息的顺序和及时性。消息认证实际上是对消息本身产生一个冗余的信息-MAC(Message Authentication Code,消息认证码),消息认证码是利用密钥对要认证的消息产生新的数据块,并对数据块加密生成的。它对于要保护的信息来说是唯一和一一对应的。因此可以有效地保护消息的完整性,以及实现发送方消息的不可抵赖和不能伪造。消息认证码的安全性取决于两点:1)采用的加密算法生成数字签名;2)待加密数据块的生成方法。用消息认证码实现消息认证可通过消息摘要方案来实现。消息摘要方案是利用目前广泛应用的单向散列函数来生成HMAC-SHA1值作为认证码。
HMAC(Keyed-hash message authentication code,基于哈希的消息认证码)是指由关键字和加密算法一起计算出来的消息加密码,能够同时验证消息真实性和数据完整性。HMAC是一种基于散列函数的消息鉴别码。它可用来检测通过不可靠媒介传输或存储的信息完整性。一般的,消息鉴别码用于验证传输于两个共同享有一个密钥的单位之间的消息。HMAC可以与任何迭代散列函数捆绑使用,MD5和SHA1就是这种散列函数。HMAC还可以使用一个用于计算和确认消息鉴别值的密钥。
目前,可供选择的散列函数有SHA1[SHA],MD5,RIPEMD-128/160[RIPEMD]。这些不同的HMAC实现被表示为,HMAC-SHA1,HMAC-MD5,HMAC-RIPEMD等等。
定义HMAC需要一个用于加密的散列函数(表示为H),一个密钥K和一个数据流text。H可以是SHA1或MD5等,它是一个将数据块用一个基本的迭代压缩函数来加密的散列函数。用B来表示数据块的字长(以上提到的散列函数的分割数据块字长B=64)。用L来表示散列函数的输出数据字长(MD5中L=16,SHA-1中L=20)。鉴别密钥的长度可以是小于等于数据块字长的任何正整数值。应用程序中使用的密钥长度若是比B大,则首先使用散列函数H作用于它,然后用H输出的L长度字符串作为在HMAC中实际使用的密钥。一般情况下,推荐的最小密钥K长度是L个字长。(与H的输出数据长度相等)。将定义两个固定且不同的字符串ipad,opad:(′i′,′o′标志内部与外部)
ipad=the byte 0x36 repeated B times
opad=the byte 0x5C repeated B times。
计算′text′的HMAC:
H(K XOR opad,H(K XOR ipad,text))
即为以下步骤:
1)在密钥K后面添加0来创建一个字长为B的字符串(例如,如果K的字长是20字节,B=64字节,则K后会加入44个零字节0x00);
2)将上一步生成的B字长的字符串与ipad做异或运算;
3)将数据流text填充至第二步的结果字符串中;
4)用H作用于第三步生成的数据流;
5)将第一步生成的B字长字符串与opad做异或运算;
6)再将第四步的结果填充进第五步的结果中;
7)用H作用于第六步生成的数据流,输出最终结果。
安全哈希算法(SHA,Secure Hash Algorithm)主要适用于数字签名标准(DSS,DigitalSignature Standard)里面定义的数字签名算法(DSA,Digital Signature Algorithm)。对于长度小于264位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。
SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要。SHA1始终把消息当成一个位(bit)字符串来处理。本文中,一个“字”(Word)是32位,而一个“字节”(Byte)是8位。比如,字符串“abc”可以被转换成一个位字符串:011000010110001001100011,它也可以被表示成16进制字符串:0x616263。
SHA1中循环左移位操作符Sn(X),其中,X是一个字,n是一个整数,0<=n<=32,Sn(X)=(X<<n)OR(X>>32-n)。
X<<n定义如下:抛弃最左边的n位数字,将其余各个位依次向左移动n位,然后用0填补右边的n位(最后结果还是32位)。
X>>n是抛弃右边的n位,将其余各个位依次向右移动n位,然后在左边的n位填0。
在SHA1算法中,必须把原始消息(字符串,文件等)转换成位字符串。SHA1算法只接受位作为输入,假设对字符串“abc”产生消息摘要。首先,将它转换成位字符串如下:
011000010110001001100011
-------------
‘a’=97‘b’=98‘c’=99
这个位字符串的长度为24位,需要5个步骤来计算SHA1:
1)补位消息必须进行补位,以使其长度在对512取模以后的余数是448。也就是说,(补位后的消息长度)%512=448,即使长度已经满足对512取模后余数是448,补位也必须要进行。补位是这样进行的:先补一个1,然后再补0,直到长度满足对512取模后余数是448,总而言之,补位是至少补一位,最多补512位,还是以前面的“abc”为例显示补位的过程:
原始信息:011000010110001001100011
补位第一步:0110000101100010011000111 首先补一个“1”
补位第二步:01100001011000100110001110...0然后补423个“0”
可以把最后补位完成后的数据用16进制写成下面的样子
61626380000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
0000000000000000
现在,数据的长度是448,可以进行下一步操作;
2)补长度
所谓的补长度是将原始数据的长度补到已经进行了补位操作的消息后面,通常用一个64
位的数据来表示原始消息的长度,如果消息长度不大于264,那么第一个字就是0,在进行了
补长度的操作以后,整个消息就变成下面这样了(16进制格式):
61626380000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000018
如果原始的消息长度超过了512,需要将它补成512的倍数,然后把整个消息分成多个长度为512位的数据块(16个字的数据块M1,M2,...,Mn),分别处理每一个数据块Mn,从而得到消息摘要;
3)使用的常量
一系列的常量字K(0),K(1),......,K(79),如果以16进制给出,它们如下:
Kt=0x5A827999(0<=t<=19)
Kt=0x6ED9EBA1(20<=t<=39)
Kt=0x8F1BBCDC(40<=t<=59)
Kt=0xCA62C1D6(60<=t<=79);
4)需要使用的函数
在SHA1中需要一系列的函数,每个函数ft(0<=t<=79)都操作32位字B,C,D并且产生32位字作为输出,ft(B,C,D)可以如下定义:
ft(B,C,D)=(B AND C)or((NOT B)AND D) (0<=t<=19)
ft(B,C,D)=B XOR C XOR D (20<=t<=39)
ft(B,C,D)=(B AND C)or(B AND D)or(C AND D)(40<=t<=59)
ft(B,C,D)=B XOR C XOR D (60<=t<=79);
5)计算消息摘要
必须使用进行了补位和补长度后的消息来计算消息摘要,计算需要两个缓冲区,每个都由5个32位的字组成,还需要80个容量为32位字的缓冲区,第一个5个字的缓冲区被标识为A,B,C,D,E。第二个5个字的缓冲区被标识为H0,H1,H2,H3,H4。80个字的缓冲区被标识为W0,W1,...,W79,另外还需要一个一个字的临时缓冲区Temp,为了产生消息摘要,前面定义的16个字的数据块M1,M2,...,Mn会依次进行处理,处理每个数据块Mi包含下述5个步骤。在处理每个数据块之前,缓冲区{Hi}被初始化为下面的值(16进制):
H0=0x67452301;H1=0xEFCDAB89;H2=0x98BADCFE;H3=0x10325476;H4=0xC3D2E1F0,
现在开始处理M1,M2,...,Mn。为了处理Mi,需要进行下面的步骤:
(1).将Mi分成16个字W0,W1,...,W15,W0是最左边的字;
(2).对于t=16到79令Wt=S1(Wt-3XORWt-8XORWt-14XORWt-16);
(3).令A=H0,B=H1,C=H2,D=H3,E=H4;
(4).对于t=0到79,执行下面的循环;
Temp=S5(A)+ft(B,C,D)+E+Wt+Kt;
E=D;D=C;C=S30(B);B=A;A=Temp;
(5).令H0=H0+A,H1=H1+B,H2=H2+C,H3=H3+D,H4=H4+E。
在处理完所有的Mn,后,消息摘要是一个160位的字符串,以下面的顺序标识H0H1H2H3H4。
SHA算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature StandardDSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。
标准的HMAC-SHA1算法,根据共享密钥Key、动态因子C、ipad求得SHA1算法第一次运行所需的消息,根据共享密钥Key、动态因子C、opad求得SHA1算法第二次运行所需的消息,消息是要全部缓存的,这造成了RAM资源的浪费,本发明中,这些消息不需要占用RAM;另外,SHA1算法在对消息处理时,要对消息补位和补长度,所补的位和长度在标准算法中需要RAM缓冲区缓存,造成了RAM资源的浪费,在本发明中,提供了不需要占用RAM的方法;密钥生成设备的不断低成本化是产品的趋势所在,由于密钥生成设备中的RAM区通常很小(256字节以内),这会导致无法有足够的RAM资源来满足HMAC-SHA1算法运算。
发明内容
为了克服现有技术的不足,本发明提供了一种生成消息认证码的方法,大大降低HMAC-SHA1算法在密钥生成设备中运算时所需RAM空间。所述技术方案如下:
一种生成消息认证码的方法,所述方法包括:
步骤A1:把数据流存入中间数据流缓冲区,用预先规定的常量分别初始化字变量1、字变量2、字变量3、字变量4和字变量5;
步骤A2:将所述字变量1、字变量2、字变量3、字变量4和字变量5分别赋给预先设定的字变量6、字变量7、字变量8、字变量9和字变量10;
步骤A3:对于计数变量取值0到79,循环计算中间量、字变量6、字变量7、字变量8、字变量9和字变量10;其中,所述计数变量的初始值为0,每循环计算一次,所述计数变量加1;每循环一次,根据当前中间量按照预设规则修改所述字变量6、字变量7、字变量8、字变量9和字变量10;所述中间量分如下两步计算:
1)如果所述计数变量取值0到15,根据预设共享密钥、所述共享密钥的长度、预设常数1和所述计数变量,计算所述中间量,具体过程如下:
步骤B1:如果计数变量的取值大于等于0且小于所述共享密钥的长度的四分之一时,把所述共享密钥分成多个字,所述多个字的个数为所述共享密钥的长度的四分之一对应的值,则当前中间量为所述多个字中所述计数变量的当前值对应的字;如果计数变量等于所述共享密钥的长度的四分之一且所述共享密钥的长度是4的整数倍,则当前中间量为0;如果计数变量等于所述共享密钥的长度的四分之一且所述共享密钥的长度不是4的整数倍,在所述共享密钥的尾部补0,使所述共享密钥的长度能够被4整除,则当前中间量为补0后的共享密钥的最后一个字;如果计数变量取值大于所述共享密钥的长度的四分之一且小于等于15,则当前中间量为0;
步骤B2:把当前中间量的每一个字节与预设常量1相异或,结果赋给当前中间量;
2)如果所述计数变量取值16到79,根据待计算的当前中间量的前16个中间量,计算所述当前中间量,具体过程如下;
步骤B1′:在中间缓冲区中缓存当前中间量的前16个中间量,依次从0至15编号,提取所述中间缓冲区中的第0、2、8、13个编号对应的中间量;
步骤B2′:对提取出的中间量进行异或运算,对异或运算的结果做循环左移1位运算,将运算后的结果作为当前中间量;
步骤B3′:用所述当前中间量更新所述中间缓冲区,使其缓存所述当前中间量及所述当前中间量的前15个中间量;
步骤A4:所述计数变量等于80时,根据如下公式:
字变量1=字变量1+字变量6,
字变量2=字变量2+字变量7,
字变量3=字变量3+字变量8,
字变量4=字变量4+字变量9,
字变量5=字变量5+字变量10;
计算当前字变量1、字变量2、字变量3、字变量4和字变量5,并将所述计数变量归0;
步骤A5:将当前的字变量1、字变量2、字变量3、字变量4和字变量5分别赋给所述字变量6、字变量7、字变量8、字变量9和字变量10;
步骤A6:对于计数变量取值0到79,循环计算中间量、字变量6、字变量7、字变量8、字变量9和字变量10;其中,所述中间量分如下两步计算:
1)如果所述计数变量取值0到15,根据所述中间数据流缓冲区中的中间数据流、所述中间数据流的长度和所述计数变量,计算所述中间量,具体如下:
如果计数变量的取值大于等于0且小于所述中间数据流的长度的四分之一时,把所述中间数据流分成多个字,所述多个字的个数为所述中间数据流的长度的四分之一对应的值,则当前中间量为所述多个字中所述计数变量的当前值对应的字;
如果计数变量等于所述中间数据流的长度的四分之一且所述中间数据流的长度是4的整数倍,则当前中间量为0X80000000;
如果计数变量等于所述中间数据流的长度的四分之一且所述中间数据流的长度不是4的整数倍,在所述中间数据流的尾部先补1,再补0,使所述中间数据流的长度能够被4整除,则当前中间量为补位后的中间数据流的最后一个字;
如果计数变量取值大于所述中间数据流的长度的四分之一且小于15,则当前中间量为0;
如果计数变量取值等于15,则当前中间量为所述中间数据流的长度乘以8加上512的结果;
2)如果所述计数变量取值16到79,根据待计算的当前中间量的前16个中间量,计算所述当前中间量,具体过程如下;
步骤B1′:在中间缓冲区中缓存当前中间量的前16个中间量,依次从0至15编号,提取所述中间缓冲区中的第0、2、8、13个编号对应的中间量;
步骤B2′:对提取出的中间量进行异或运算,对异或运算的结果做循环左移1位运算,将运算后的结果作为当前中间量;
步骤B3′:用所述当前中间量更新所述中间缓冲区,使其缓存所述当前中间量及所述当前中间量的前15个中间量;
步骤A7:所述计数变量等于80时,根据所述步骤A1中计算出的字变量1、字变量2、字变量3、字变量4和字变量5,以及所述步骤A6中计算出的字变量6、字变量7、字变量8、字变量9和字变量10,根据如下公式:
字变量1=字变量1+字变量6,
字变量2=字变量2+字变量7,
字变量3=字变量3+字变量8,
字变量4=字变量4+字变量9,
字变量5=字变量5+字变量10;
计算当前字变量1、字变量2、字变量3、字变量4和字变量5;并将所述计数变量归0;
步骤A8:将当前的字变量1、字变量2、字变量3、字变量4和字变量5分别装载到所述中间数据流缓冲区,用所述预先规定的常量分别初始化当前的字变量1、字变量2、字变量3、字变量4和字变量5;
步骤A9:将当前的字变量1、字变量2、字变量3、字变量4和字变量5分别赋给所述字变量6、字变量7、字变量8、字变量9和字变量10;
步骤A10:对于计数变量取值0到79,循环计算中间量、字变量6、字变量7、字变量8、字变量9和字变量10;其中,所述中间量分如下两步计算:
1)如果所述计数变量取值0到15,根据预设共享密钥、所述共享密钥的长度、预设常数2和所述计数变量,计算所述中间量,具体过程如下:
步骤B1″:如果计数变量的取值大于等于0且小于所述共享密钥的长度的四分之一时,把所述共享密钥分成多个字,所述多个字的个数为所述共享密钥的长度的四分之一对应的值,则当前中间量为所述多个字中所述计数变量的当前值对应的字;如果计数变量等于所述共享密钥的长度的四分之一且所述共享密钥的长度是4的整数倍,则当前中间量为0;如果计数变量等于所述共享密钥的长度的四分之一且所述共享密钥的长度不是4的整数倍,在所述共享密钥的尾部补0,使所述共享密钥的长度能够被4整除,则当前中间量为补0后的共享密钥的最后一个字;如果计数变量取值大于所述共享密钥的长度的四分之一且小于等于15,则当前中间量为0;
步骤B2″:把当前中间量的每一个字节与预设常量2相异或,结果赋给当前中间量;
2)如果所述计数变量取值16到79,根据待计算的当前中间量的前16个中间量,计算所述当前中间量具体过程如下;
步骤B1′:在中间缓冲区中缓存当前中间量的前16个中间量,依次从0至15编号,提取所述中间缓冲区中的第0、2、8、13个编号对应的中间量;
步骤B2′:对提取出的中间量进行异或运算,对异或运算的结果做循环左移1位运算,将运算后的结果作为当前中间量;
步骤B3′:用所述当前中间量更新所述中间缓冲区,使其缓存所述当前中间量及所述当前中间量的前15个中间量;
步骤A11:所述计数变量等于80时,根据所述步骤A1中计算出的字变量1、字变量2、字变量3、字变量4和字变量5,以及所述步骤A10中计算出的字变量6、字变量7、字变量8、字变量9和字变量10,根据如下公式:
字变量1=字变量1+字变量6,
字变量2=字变量2+字变量7,
字变量3=字变量3+字变量8,
字变量4=字变量4+字变量9,
字变量5=字变量5+字变量10;
计算当前字变量1、字变量2、字变量3、字变量4和字变量5;并将所述计数变量归0;
步骤A12:将当前的字变量1、字变量2、字变量3、字变量4和字变量5分别赋给所述字变量6、字变量7、字变量8、字变量9和字变量10;
步骤A13:重复执行所述步骤A6;
步骤A14:所述计数变量等于80时,根据所述步骤A1中计算出的字变量1、字变量2、字变量3、字变量4和字变量5,以及所述步骤A13中计算出的字变量6、字变量7、字变量8、字变量9和字变量10,根据如下公式:
字变量1=字变量1+字变量6,
字变量2=字变量2+字变量7,
字变量3=字变量3+字变量8,
字变量4=字变量4+字变量9,
字变量5=字变量5+字变量10;
计算当前字变量1、字变量2、字变量3、字变量4和字变量5;
步骤A15:将当前的字变量1、字变量2、字变量3、字变量4和字变量5作为消息认证码。
所述步骤A1中的预先规定的常量为0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0。
本发明实施例提供的技术方案的有益效果是:
本发明不需要在密钥生成设备内部单独分配RAM,用于缓存消息、消息的补位、补长度等数据,因为这些数据是在需要时是通过计算得到的,大大降低了在运算过程中所需的RAM资源,能够广泛应用于RAM资源很少的低成本密钥生成设备中,有利地降低设备成本,提高了设备应用的竞争力。
附图说明
图1是本发明实施例提供的生成消息认证码的方法流程图。
具体实施方式
为使本发明的目的、技术方案和优点更加清楚,下面将结合附图对本发明实施方式作进一步地详细描述。
为使本发明的目的、技术方案和优点更加清楚,以USB接口的一次性密码生成设备为例,来具体说明该设备中采用改进后HMAC-SHA1算法生成消息认证码的过程。在本实施例中,USB接口的一次性密码生成设备简称USB Key,首先需要进行如下初始化过程:
共享密钥K为8字节,数据流text为4字节;HMAC-SHA1算法有两个输入,分别是共享密钥K和数据流Text,而输出是20字节数据,即消息认证码,本实施例将消息认证码放在字变量1、字变量2、字变量3、字变量4和字变量5中,其中,字变量1、字变量2、字变量3、字变量4和字变量5分别用H0、H1、H2、H3、H4表示;同时,本发明中需要用到16字的中间缓冲区U,密钥缓冲区K,20字节中间数据流缓冲区Data,一个32位字临时缓冲区Temp,32位字的字变量6、字变量7、字变量8、字变量9和字变量10,其中,字变量6、字变量7、字变量8、字变量9和字变量10分别用A、B、C、D、E表示,以及用于循环计数的单字节计数变量t、i和j,预设常数1和常数2分别为常数ipad:0x36,常数opad:0x5c;密钥长度KLEN,数据流长度DLEN;中间量Wt是一个符号,表示一个32位的字,t是下标,t可变;
本发明实施例提供的生成认证码的方法通过两次调用散列函数生成消息认证码,参见图1,该方法具体包括:
步骤101:把数据流text存入中间数据流缓冲区Data,DLEN等于数据流长度TLEN,用预先规定的常量分别初始化H0、H1、H2、H3和H4;计数变量i和j都初始化为1;
例如:本实施例采用的预先规定的常数分别为0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0,将这五个常量分别赋给H0,H1,H2,H3,H4;
步骤102:把H0、H1、H2、H3、H4分别赋给A、B、C、D、E,并计数变量t设置为初始值0;即令A=H0;B=H1;C=H2;D=H3;E=H4;
步骤103:判断计数变量t是否小于80,如果是,执行步骤104;否则,执行步骤106;
步骤104:对于计数变量t取值0到79,循环计算中间量Wt;中间量Wt分如下两步计算:
1)计数变量t取值0到15
当i=1,j=1时,根据K、KLEN、ipad、t运用预先规定的算法计算中间量Wt;
当i=1或2,j=2时,根据中间数据流Data、DLEN、t运用另一个预先规定的算法计算中间量Wt;
当i=2,j=1时,根据K、KLEN、opad、t运用预先规定的算法计算中间量Wt;
2)计算计数变量t取值16到79
根据计算的当前中间量Wt的前16个中间量,运用另一个预先规定的算法计算当前中间量Wt;
步骤105:计算完当前的中间量Wt后,根据当前的中间量Wt修改字变量A,B,C,D,E,并将计数变量t加1;
步骤106:根据如下公式计算H0,H1,H2,H3,H4,计算完成后,并将计数变量j加1;
H0=H0+A,H1=H1+B,H2=H2+C,H3=H3+D,H4=H4+E;
步骤107:判断j是否小于等于2,如果是,返回步骤102;否则,执行步骤108;
步骤108:将j置为1,i加1;
步骤109:判断i是否小于等于2,如果是,执行步骤110;否则,执行步骤111;
步骤110:将H0,H1,H2,H3,H4分别装载到中间数据流缓冲区Data,并用上述预先规定的常量分别初始化H0,H1,H2,H3,H4;然后返回步骤102;
步骤111:将当前的H0,H1,H2,H3,H4作为消息认证码,并结束。
进一步地,上述步骤104中Wt的具体计算过程分以下情况计算:
1)对于t取值0到15,当i=1,j=1时,根据K、KLEN、ipad、t来计算中间量Wt的步骤可以通过以下方法实现:
如果t取值大于等于0且小于(KLEN/4),把K分成KLEN/4个字,则当前Wt是组成K的第t个字;
如果t等于(KLEN/4)且KLEN是4的整数倍,可得到Wt为0;
如果t等于(KLEN/4)且KLEN不是4的整数倍,则当前Wt由K中第(KLEN/4)*4个字节到K中最后一个字节和若干个所补的0组成;
如果t取值大于(KLEN/4)却小于等于15,可得到Wt为0;
然后,把组成Wt的每一个字节与ipad相异或,再将异或后的结果赋给Wt。
当i=1或2,j=2时,根据Data、DLEN、t来计算Wt的过程如下:
如果t取值大于等于0且小于(DLEN/4),把Data分成DLEN/4个字,则当前Wt是组成Data的第t个字;
如果t等于(DLEN/4)且DLEN是4的整数倍,可得到Wt为Data所补的第一个字,例如0x80000000;
如果t等于(DLEN/4)且DLEN不是4的整数倍,则当前Wt由Data中第(DLEN/4)*4个字节到Data中最后一个字节、所补的1和若干个所补的0组成;
如果t取值大于(DLEN/4)却小于等于14,可得到Wt为0;如果t等于15,当前Wt为Data所补的长度,具体为DLEN乘以8加上512的结果。
当i=2,j=1时,根据K、KLEN、opad、t来计算Wt的过程如下:
如果t取值大于等于0且小于(KLEN/4),把K分成KLEN/4个字,则当前Wt是组成K的第t个字;
如果t等于(KLEN/4)且KLEN是4的整数倍,可得到Wt为0;
如果t等于(KLEN/4)且KLEN不是4的整数倍,则当前Wt由K中第(KLEN/4)*4个字节到K中最后一个字节和若干个所补的0组成;
如果t取值大于(KLEN/4)却小于等于15,可得到Wt为0。
2)如果t取值16到79,根据Wt的前16个中间量计算当前Wt的步骤可以通过以下方法实现:
因为在16字的中间缓冲区U中缓存了Wt的前16个中间量Wt-16,Wt-15,...,Wt-1;U0,U2,U8,U13分别是中间缓冲区U中的第0、2、8、13个数;
用U0、U2、U8、U13相互异或,即:U0xorU2xor U8xor U13,对异或的结果再做循环左移1位运算,运算后的结果作为当前的Wt;
然后更新中间缓冲区U,使其缓存当前Wt及当前Wt前面15个中间量。具体实现是,对于k在0~14之间,循环使Uk等于Uk+1;U15等于Wt;其中k+1是下标。
进一步地,步骤105中根据当前的Wt修改A、B、C、D、E的步骤的实现过程如下:
A循环左移5位的结果,加上E,加上当前的Wt值,加上Kt,再加上Ft,结果暂存在Temp中;然后把D赋给E;把C赋给D;把B循环左移30位赋给C;把A赋给B;把Temp赋给A;即表示为:Temp=S5(A)+E+Wt+Kt+Ft;E=D;D=C;C=S30(B);B=A;A=Temp;
其中,Kt的计算方法为:对于t小于20,Kt等于0x5A827999;对于t大于等于20且小于40,Kt等于0x6ED9EBA1;对于t大于等于40且小于60,Kt等于0x8F1BBCDC;对于t大于等于60且小于80,Kt等于0xCA62C1D6;
Ft的计算方法为:先把B和C进行逻辑与运算的结果放在Temp中,然后对B进行逻辑取反运算后结果和D进行逻辑与运算,这次的运算结果和之前的Temp再进行逻辑或运算,就得到t小于20时的Ft值;B、C、D相异或运算后的结果,就是t大于等于20且小于40时的Ft,也是t大于等于60且小于80时的Ft;我们把B和C进行逻辑与运算的结果放在Temp中;B和D进行逻辑与运算的结果再和Temp进行逻辑或运算,结果再放在Temp中;B和D进行逻辑与运算的结果再和Temp进行逻辑或运算,结果就是t大于等于40且小于60时的Ft。
在HMAC-SHA1算法中,在其所用的SHA1算法内,关于t=0至t=79时,Wt的计算程序代码如下:
/*计算t=0至t=79时Wt,每计算一个Wt,运算得到对应的A,B,C,D,E*/
for(t=0;t<80;t++)
{
if(t<16)//计算t<16时的Wt(即Temp)
{
//SHA1算法的Message补位后,可分成2个64字节块;故i<2;
if(i==0)//i=0,则进行块0(64字节)运算
{ //得到key数据的填充数,即Wt,也即Temp
Temp=dw_pad^getvalue1(t,K,KLEN);
}
else if(i==1) //i=1,则进行块1(64字节)运算
{ //得到Data数据后的填充数,即Wt,也即Temp
Temp=getvalue2(t,Data,DLEN);
}
U[t]=Temp; //计算后的填充数放到16字缓冲区U中
}
else //计算16=<t<=79时的Wt(即Temp)
{ Temp=rotl(1,(U[13]^U[8]^U[2]^U[0]));
for(j=0;j<15;j++) //更新16字缓冲区U
{U[j]=U[j+1];}
U[j]=Temp;
}
Temp=rotl(5,a)+ft(t,b,c,d)+e+Temp+K(t);;
e=d;
d=c;
c=rotl(30,b);//字b循环左移30位
b=a;
a=Temp;
} //for(...)
unsigned int getvalue1(unsigned char t,unsigned char*pKey,unsigned char keylen)
{ unsigned int w=0;
if(t<(keylen/4))
{ w=(((unsigned int)*(pKey+4*t))<<24)|
(((unsigned int)*(pKey+4*t+1))<<16)|
(((unsigned int)*(pKey+4*t+2))<<8)|
((unsigned int)*(pKey+4*t+3));
}
return w;
}
unsigned int getvalue2(unsigned char t,unsigned char*pData,unsigned char len)
{ unsigned int w;
if(t<(len/4))
{ w=(((unsigned int)*(pData+4*t))<<24)|
(((unsigned int)*(pData+4*t+1))<<16)|
(((unsigned int)*(pData+4*t+2))<<8)|
((unsigned int)*(pData+4*t+3));
}
else if(t==(len/4)){w=0x80000000;}
else if(t==15){w=0x200|((unsigned int)(len*8));}
else{w=0;}
return w;
}
在本发明实施例中,HMAC-SHA1算法运算中即不计算消息,也不需要缓存消息,计算中间结果Wt的过程通过即时计算一个Wt,然后用该Wt产生中间结果A、B、C、D、E;通过步骤104可以求到HMAC-SHA1算法中所需的消息中任一个数、消息的补位数据、消息的补长度数据,这种运算共用算法运算所需的临时缓冲Temp、16字的算法中间缓冲区U,不需要为其单独分配运算缓冲区。而标准算法中,不仅单独分配缓冲区缓存了消息、而且缓存了消息补位、消息补长度,所有这些占用了大量RAM,限制了HMAC-SHA1算法在RAM资源有限的设备中的应用;
以共享密钥8字节,数据流4字节为例;在现有技术中的HMAC-SHA1算法,第一次被调SHA1算法所需消息所需68字节RAM,消息的消息补位、补长度分别增加60字节RAM占用;第二次被调SHA1算法所需消息所需84字节RAM,消息补位、补长度增加44字节RAM占用;所以其必然最少用128字节RAM来缓存消息及其补位、补长度数据;
使用本发明中改进后的HMAC-SHA1算法,无需缓存上述缓存消息及其补位、补长度数据,即在密钥生成设备中,需0字节RAM,这些算法所需的填充数据是可以由密钥生成设备中的程序即时生成。
以上对本发明所提供的一种密钥生成设备中的生成消息认证码的方法进行了详细介绍,本文中应用了具体个例对本发明的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本发明的方法及其核心思想;同时,对于本领域的一般技术人员,依据本发明的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本发明的限制。