1.HMAC算法
HMAC是一种基于Hash函数和密钥进行消息认证的方法,通过这个算法可以保证通信双方之前交互的消息来自对方并且没有被篡改。
HMAC的作用:
[1]可以保证消息不被篡改,因为有Hash算法来保证。
[2]认证信源身份,因为有密钥来保证。
即所谓HMAC算法就是通过提供一个Hash函数,一个key,一个字符串来计算出一个值。通信双方约定好key之后,双方各自使用这个算法交换算法结果来保证双方之前交互过的消息来自对方并且没有被篡改。
很明显HMAC算法的输入是:消息+key,并且提供一个Hash函数(例如MD5)。输出就是一个字符串(如果是MD5,则这个字符串长度是16字节,如果是SHA1则是20字节)。
示例:ssl握手的最后一步,客户端把握手的所有消息使用HMAC算法计算出一个值发送给服务器,服务器也做同样的操作发送给客户端。两端通过比较自己的值和收到的值,来保证ssl握手时的消息没有被篡改。
2.HMAC-MD5算法
HMAC-MD5算法就是HMAC算法的一个特例,即用md5作为HMAC的Hash函数。
计算流程:
(1) 在密钥key后面添加0来创建一个长为B(64字节)的字符串(str),如果key超过64字节则使用key的md5代替key,再在后面加0补齐64字节。
(2) 将上一步生成的字符串(str)与ipad(0x36)做异或运算,形成结果字符串(istr)。
(3) 将数据流data附加到第二步的结果字符串(istr)的末尾。
(4) 做md5运算于第三步生成的数据流(istr)。
(5) 将第一步生成的字符串(str) 与opad(0x5c)做异或运算,形成结果字符串(ostr)。
(6) 再将第四步的结果(istr) 附加到第五步的结果字符串(ostr)的末尾(7) 做md5运算于第6步生成的数据流(ostr),最终输出结果(out)。
3.HMAC-MD5算法实现
int hmac_md5(unsigned char *key, int key_len, unsigned char *data, int data_len, unsigned char *out, int olen)
{
unsigned i;
unsigned char tk[64],tktemp[64];
unsigned char *p;
// 如果密钥长度大于64,使用key的md5值替换key
if(key_len > 64){
md5(key, key_len, tktemp);
key_len = 16;
}else{
memcpy(tktemp, key, key_len);
}
p = (unsigned char *)malloc(64 + (data_len > 16 ?(data_len):16));
if(NULL == p)
return -1;
// key后面置0,补齐64个字节
lite_proxy_memcpy(p, tktemp, key_len);
lite_proxy_memset(p+key_len,0,64-key_len);
//与0x36相异或
for(i=0; i<64; i++)
p[i]^=0x36;
memcpy(p+64, data, data_len);
md5(p, 64+data_len, tk);
lite_proxy_memcpy(p,tktemp,key_len);
lite_proxy_memset(p+key_len,0,64-key_len);
/*与0x5c异或*/
for(i=0; i<64; i++)
p[i]^=0x5c;
memcpy(p+64, tk, 16);
md5(p, 64+16, out);
free(p);
return 0;
}
4.问题
[1]HMAC的作用是保证之前交互的消息没有被篡改并且来自对方(key来保证)。因此对于ssl,客户端和服务器可以把(握手的消息+key)做md5,直接使用md5算法来代替HMAC-MD5算法,为什么ssl协议没有这么做。
其实把(握手的消息+key)做md5,这个已经接近HMAC算法,因为HMAC算法就是把key混到data里面做一系列运算。只不过这一系列运算(HMAC)得到的结果比直接(握手的消息+key)做md5结果更加安全。
这也说明HMAC算法的本质就是md5(数据+key)。
原文:https://www.cnblogs.com/iamwho/p/11800017.html