HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。

 

原理

    它需要一个加密用散列函数(表示为H,可以是MD5或者SHA-1)和一个密钥K用以计算消息认证码。

    计算HMAC需要一个散列函数hash(可以是md5或者sha-1)和一个密钥key。用L表示hash函数输出字符串长(md5是16),用B表示数据块的长度(md5和sha-1的分割数据块长都是64)。密钥key的长度可以小于等于数据块长B,如果大于数据块长度,可以使用hash函数对key进行转换,结果就是一个L长的key。
  然后创建两个B长的不同字符串:
  innerpad = 长度为B的 0×36
  outterpad = 长度为B的 0×5C
  计算输入字符串str的HMAC:
  hash(key ^ outterpad, hash(key ^ innerpad, str))

 

应用

    1、HMAC的一个典型应用是用在“质疑/应答”(Challenge/Response)身份认证中。
认证流程:

    (1) 先由客户端向服务器发出一个验证请求。
    (2) 服务器接到此请求后生成一个随机数并通过网络传输给客户端(此为质疑)。
    (3) 客户端将该随机值作为密钥,用户密码进行hmac运算,然后提交给服务器(此为响应)。
    (4) 与此同时,服务器也使用该随机数与存储在服务器数据库中的该客户密钥进行hmac运算,如果服务器的运算结果与客户端传回的响应结果相同,则认为客户端是一个合法用户。

    2、用来做消息的完整性检查。

      通讯双方A和B共享一个secret key, A方在发送数据给B的时候,先对要发送信息做一个Hashing操作(MD5 Hashing 或 SHA-1 Hashing),然后再将结果和这个共享的secret key连接在一起再做Hashing操作,将最后结果随信息一起发给B. B在接收到这个信息时,也对信息做同样操作,如果结果跟A发过来的一致,则认证通过;否则,丢弃该信息包。具体参考RFC 2104文档。https://www.ietf.org/rfc/rfc2104.txt

 

安全性

    由上面的介绍,我们可以看出,HMAC算法更象是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的HASH算法,安全性主要有如下保证:

    (1) 使用的密钥是双方事先约定的,第三方不可能知道。由介绍的应用流程可以看出,作为非法截获信息的第三方,能够得到的信息只有作为“质疑”的随机数和作为“响应”的HMAC结果,无法根据这两个数据逆向推算出密码。           

  在这个过程中,可能遭到安全攻击的是服务器发送的随机值和用户发送的hmac结果,而对于截获了这两个值的黑客而言这两个值是没有意义的,绝无获取用户密码的可能性,随机值的引入使hmac只在当前会话中有效,大大增强了安全性和实用性。大多数的语言都实现了hmac算法,比如php的mhash、python的hmac.py、java的MessageDigest类,在web验证中使用hmac也是可行的,用js进行md5运算的速度也是比较快的。