HMAC MD5算法原理及用处

来源:互联网 发布:大学生网络党校首页 编辑:程序博客网 时间:2024/06/05 15:55

        MD5和SHA-1是一种HASH函数,又称杂凑函数,类似于指纹的应用。在网络安全协议中,杂凑函数用来处理电子签名,将冗长的签名文件压缩为一段独特的数字信息,像指纹鉴别身份一样保证原来数字签名文件的合法性和安全性。经过这些算法的处理,原始信息即使只更动一个字母,对应的压缩信息也会变为截然不同的“指纹”,这就保证了经过处理信息的唯一性。为电子商务等提供了数字认证的可能性。
而HMAC算法需要一个加密用散列函数(表示为H,可以是MD5或者SHA-1)和一个密钥K。我们用B来表示数据块的字节数。(以上所提到的散列函数的分割数据块字长B=64),用L来表示散列函数的输出数据字节数(MD5中L=16,SHA-1中L=20)。鉴别密钥的长度可以是小于等于数据块字长的任何正整数值。应用程序中使用的密钥长度若是比B大,则首先用使用散列函数H作用于它,然后用H输出的L长度字符串作为在HMAC中实际使用的密钥。一般情况下,推荐的最小密钥K长度是L个字节。

  我们将定义两个固定且不同的字符串ipad,opad:(‘i','o'标志内部与外部)
  ipad = the byte 0x36 重复 B 次
  opad = the byte 0x5C 重复 B 次.
  计算‘text'的HMAC:
  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作用于第六步生成的数据流,输出最终结果

HMAC的典型应用

  HMAC的一个典型应用是用在“挑战/响应”(Challenge/Response)身份认证中,认证流程如下[3]:
   (1) 先由客户端向服务器发出一个验证请求。
   (2) 服务器接到此请求后生成一个随机数(text)并通过网络传输给客户端(此为挑战)。
   (3) 客户端将收到的随机数提供给ePass,由ePass使用该随机数(text)与存储在ePass中的密钥(K)进行HMAC-MD5运算并得到一个结果作为认证证据传给服务器(此为响应)。

   (4) 与此同时,服务器也使用该随机数与存储在服务器数据库中的该客户密钥进行HMAC-MD5运算,如果服务器的运算结果与客户端传回的响应结果相同,则认为客户端是一个合法用户

 /*** Function: hmac_md5*/voidhmac_md5(text, text_len, key, key_len, digest)unsigned char*  text;                /* pointer to data stream */int             text_len;            /* length of data stream */unsigned char*  key;                 /* pointer to authentication key */int             key_len;             /* length of authentication key */caddr_t         digest;              /* caller digest to be filled in */{        MD5_CTX context;        unsigned char k_ipad[65];    /* inner padding -                                      * key XORd with ipad                                      */        unsigned char k_opad[65];    /* outer padding -                                      * key XORd with opad                                      */        unsigned char tk[16];        int i;        /* if key is longer than 64 bytes reset it to key=MD5(key) */        if (key_len > 64) {                MD5_CTX      tctx;                MD5Init(&tctx);                MD5Update(&tctx, key, key_len);                MD5Final(tk, &tctx);                key = tk;                key_len = 16;        }        /*         * the HMAC_MD5 transform looks like:         *         * MD5(K XOR opad, MD5(K XOR ipad, text))         *         * where K is an n byte key         * ipad is the byte 0x36 repeated 64 times         * opad is the byte 0x5c repeated 64 times         * and text is the data being protected         */        /* start out by storing key in pads */        bzero( k_ipad, sizeof k_ipad);        bzero( k_opad, sizeof k_opad);        bcopy( key, k_ipad, key_len);        bcopy( key, k_opad, key_len);        /* XOR key with ipad and opad values */        for (i=0; i<64; i++) {                k_ipad[i] ^= 0x36;                k_opad[i] ^= 0x5c;        }        /*         * perform inner MD5         */        MD5Init(&context);                   /* init context for 1st                                              * pass */        MD5Update(&context, k_ipad, 64)      /* start with inner pad */        MD5Update(&context, text, text_len); /* then text of datagram */        MD5Final(digest, &context);          /* finish up 1st pass */        /*         * perform outer MD5         */        MD5Init(&context);                   /* init context for 2nd                                              * pass */        MD5Update(&context, k_opad, 64);     /* start with outer pad */        MD5Update(&context, digest, 16);     /* then results of 1st                                              * hash */        MD5Final(digest, &context);          /* finish up 2nd pass */}Test Vectors (Trailing '\0' of a character string not included in test):  key =         0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b  key_len =     16 bytes  data =        "Hi There"  data_len =    8  bytes  digest =      0x9294727a3638bb1c13f48ef8158bfc9d  key =         "Jefe"  data =        "what do ya want for nothing?"  data_len =    28 bytes  digest =      0x750c783e6ab0b503eaa86e310a5db738  key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA  key_len       16 bytes  data =        0xDDDDDDDDDDDDDDDDDDDD...                ..DDDDDDDDDDDDDDDDDDDD...                ..DDDDDDDDDDDDDDDDDDDD...                ..DDDDDDDDDDDDDDDDDDDD...                ..DDDDDDDDDDDDDDDDDDDD  data_len =    50 bytes  digest =      0x56be34521d144c88dbb8c733f0e8b3f6



原创粉丝点击