在密码学中,(消息认证码)Message Authentication Code 是用来认证消息的比较短的信息。
换言之,MAC用来保证消息的数据完整性和消息的数据源认证
MAC由消息本身和一个密钥经过一系列计算产生,用于生成MAC的算法,称为MAC算法。
MAC算法应能满足如下几个条件:
在仅有消息本身没有密钥的情况下,无法得到该消息的 MAC
同一个消息在使用不同密钥的情况下,生成的 MAC 应当无关联
在已有一系列消息以及其 MAC 时,给定一个新的消息,无法得到该消息的 MAC
上图为维基百科上 MAC 算法使用示例。
HMAC
HMAC(Hash-based Message Authentication Code,哈希消息认证码)利用哈希算法
,以一个密钥和一个消息为输入,生成一个消息摘要作为输出
HMAC 是 IP 安全里必须实现的 MAC 方案,并且其他 Internet 协议中(如SSL)也使用了 HMAC。
HMAC的设计目标
- 可以直接使用现成的 Hash 函数
- 很容易用更好地 Hash 函数替代原来嵌入的 Hash 函数
- 能够保持 Hash 函数的原有性能,不能过分降低其性能
- 对密钥的使用和处理应较简单
- 如果已知嵌入的 Hash 函数的强度,完全可以知道认证机制抗密码分析的强度
正是 HMAC 的这些设计目标保证了HMAC的灵活性、可用性和扩展性,从而得到了广泛的支持。
定义 HMAC 需要一个加密用散列函数(表示为 H,可以是 MD5 或者 SHA-1)和一个密钥 K。我们用 B 来表示数据块的字节数。(以上所提到的散列函数的分割数据块字长 B=64),用 L 来表示散列函数的输出数据字节数(MD5 中 L=16, SHA-1 中 L=20)。鉴别密钥的长度可以是小于等于数据块字长的任何正整数值。应用程序中使用的密钥长度若是比 B 大,则首先用使用散列函数 H 作用于它,然后用 H 输出的L长度字符串作为在 HMAC 中实际使用的密钥。
一般情况下,推荐的最小密钥 K 长度是 L 个字节。
算法表示
算法公式 :
HMAC( K, M ) = H( K⊕Opad | H( K⊕Ipad | M) )
H 代表所采用的HASH算法(如SHA-256)
K 代表认证密钥
Ko 代表HASH算法的密文
M 代表一个消息输入
B 代表H中所处理的块大小,这个大小是处理块大小,而不是输出 hash 的大小
如,SHA-1 和 SHA-256 B = 64
SHA-384 和 SHA-512 B = 128
L 表示 hash 的大小
Opad 用 0x5c 重复 B 次
Ipad 用 0x36 重复 B 次
Apad 用 0x878FE1F3 重复 (L/4) 次
HMAC运算步骤
First-Hash = H( Ko XOR Ipad || (data to auth) )
Second-Hash = H( Ko XOR Opad || First-Hash)
- 在密钥 K 后面添加0来创建一个字长为 B 的字符串。(例如,如果 K 的字长是20字节,B=64 字节,则K后会加入44个零字节0x00)
- 将上一步生成的 B 字长的字符串与 ipad 做异或运算
- 将数据流 text 填充至第二步的结果字符串中
- 用 H 作用于第三步生成的数据流
- 将第一步生成的 B 字长字符串与 opad 做异或运算
- 再将第四步的结果填充进第五步的结果中
- 用 H 作用于第六步生成的数据流,输出最终结果
HMAC的应用
HMAC 主要应用在身份验证
中,它的使用方法是这样的:
- 客户端发出登录请求(假设是浏览器的GET请求)
- 服务器返回一个随机值,并在会话中记录这个随机值
- 客户端将该随机值作为密钥,用户密码进行 HMAC 运算,然后提交给服务器
- 服务器读取用户数据库中的用户密码和步骤2中发送的随机值做与客户端一样的 HMAC 运算,然后与用户发送的结果比较,如果结果一致则验证用户合法
在这个过程中,可能遭到安全攻击的是服务器发送的随机值和用户发送的 HMAC 结果,而对于截获了这两个值的黑客而言这两个值是没有意义的,绝无获取用户密码的可能性。
随机值的引入使 HMAC 只在当前会话中有效,大大增强了安全性和实用性。