Hash Mac And Hmac

Hash, MAC,HMAC
Hash-MD5, SHA-1, integrity
http://www.cnblogs.com/songhan/archive/2012/07/29/2613898.html

MAC- keyed hash, integrity & authenticity. HMAC 长度和其所用的hash长度一样

Hash

是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。

如果两个散列值是不相同的(根据同一函数),那么这两个散列值的原始输入也是不相同的。

这个特性是散列函数具有确定性的结果,具有这种性质的散列函数称为单向散列函数。

但另一方面,散列函数的输入和输出不是唯一对应關係的,如果两个散列值相同,两个输入值很可能是相同的。

但也可能不同,這種情況稱為「碰撞」,這通常是兩個不同長度的散列值,刻意計算出相同的輸出值。

Hash,一般翻译做“散列”,也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。

简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

HASH主要用于信息安全领域中加密算法,他把一些不同长度的信息转化成杂乱的128位的编码里,叫做HASH值. 也可以说,hash就是找到一种数据内容和数据存放地址之间的映射关系

了解了hash基本定义,就不能不提到一些著名的hash算法,MD5 和 SHA1 可以说是目前应用最广泛的Hash算法。

MD5(RFC1321) 是 Rivest 于 1991 年对 MD4 的改进版本,将任意长的明文 hash 成 128 bit 的杂凑值。

MD5是一种不可逆的加密算法,目前是最牢靠的加密算法之一,尚没有能够逆运算的程序被开发出来,它对应任何字符串都可以加密成一段唯一的固定长度的代码。
那么它有什么用呢?很简单,通过它可以判断原始值是否正确(是否被更改过)。一般用于密码的加密。而我们所提供的MD5校验码就是针对安装程序的唯一对应的一段代码。你可以使用任何MD5运算器对下载的文件进行运算,运算出来的结果如果完全符合我们提供的MD5校验码,那么说明你下载的这个程序没有被中途修改过。
这个特征码有如下特性,首先它不可逆,例如我有一段秘密的文字如:"My Secret Words",经算法变换后得到MD5码(b9944e9367d2e40dd1f0c4040d4daaf7),把这个码告诉其他人,他们根据这个MD5码是没有系统的方法可以知道你原来的文字是什么的。
其次,这个码具有高度的离散性,也就是说,原信息的一点点变化就会导致MD5的巨大变化,例如"ABC" MD5(902fbdd2b1df0c4f70b4a5d23525e932)和"ABC "(多了一空格)MD5(12c774468f981a9487c30773d8093561)差别非常大,而且之间没有任何关系,也就是说产生的MD5码是不可预测的。
最后由于这个码有128位那么长,所以任意信息之间具有相同MD5码的可能性非常之低,通常被认为是不可能的。
所以一般认为MD5码可以唯一地代表原信息的特征,通常用于密码的加密存储,数字签名,文件完整性验证等。

SHA1 是由 NIST NSA 设计为同 DSA 一起使用的,sha 是 Secure Hash algorithm 的缩写;它对长度小于 2^64 的输入,产生长度为 160bit 的散列值; SHA-1 设计时基于和 MD4 相同原理,并且模仿了该算法。

SHA1是由NIST NSA设计为同DSA一起使用的,它对长度小于264的输入,产生长度为160bit的散列值,因此抗穷举(brute-force)性更好。SHA-1 设计时基于和MD4相同原理,并且模仿了该算法。SHA-1是由美国标准技术局(NIST)颁布的国家标准,是一种应用最为广泛的hash函数算法,也是目前最先进的加密技术,被政府部门和私营业主用来处理敏感的信息。而SHA-1基于MD5,MD5又基于MD4。

2012080212044059.jpg

http://blog.csdn.net/showfray/article/details/2067362

http://blog.csdn.net/miaouu/article/details/6058126

MAC

消息认证码(带密钥的Hash函数):密码学中,通信实体双方使用的一种验证机制,保证消息数据完整性的一种工具。

安全性依赖于Hash函数,故也称带密钥的Hash函数。消息认证码是基于密钥和消息摘要【hash】所获得的一个值,可用于数据源发认证和完整性校验。

1. 发送者通过MAC算法计算出消息的MAC值,并和消息一起发给收信者

2. 收信者用同样的MAC算法计算收到的消息的MAC值,并对比两者。

2012072911095143.png

HMAC

介绍:

Hash-based message authentication code,利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。

a specific construction for calculating a message authentication code (MAC) involving a cryptographic hash function in combination with a secret cryptographic key. As with any MAC, it may be used to simultaneously verify both the data integrity and the authenticity of a message.【主要是为了能让人对对方身份正确性和消息有效性进行验证,与消息摘要的最大不同,就是有签名密钥!】

方法:

HMAC(K,m) = H((K ⊕ opad) ∥ H((K ⊕ ipad) ∥ m))

【opad重复0x36,ipad重复0x5C】

通过两次hash两个不同的key来生成。 还没有发现有任何的方法来产生碰撞。

步骤:

First-Hash: H(Ko XOR Ipad || (data to auth))

Second-Hash: H(Ko XOR Opad || First-Hash)

1. 字符含义

  H 代表所采用的HASH算法(如SHA-256)

  K 代表认证密码

  B 代表H中所处理的块大小,这个大小是处理块大小,而不是输出hash的大小 【SHA-1和SHA-256 B = 64,SHA-384和SHA-512 B = 128 】

  Ko 代表HASH算法的密文 【在密钥K后面添加0来创建一个字长为B的字符串。(例如,如果K的字长是20字节,B=64字节,则K后会加入44个零字节0x00)

  Opad 用0x5a重复B次
  Ipad 用0x36重复B次

2. Ko与ipad做异或运算。

3. 将数据流text填充至第2步的结果字符串中

4. 用H作用于第3步生成的数据流。

5. Ko与opad做异或运算。

6. 再将第4步的结果填充进第5步的结果中。

7. 用H作用于第6步生成的数据流,输出最终结果

e61190ef76c6a7ef9be7aaa2fdfaaf51f2de6674.jpg

应用:

HMAC的一个典型应用是用在“挑战/响应”(Challenge/Response)身份认证中

1. 客户端向服务器发出一个验证请求

2. 服务器接到此请求后生成一个随机数并通过网络传输给客户端(此为挑战)

3. 客户端将收到的随机数提供给ePass,由ePass使用该随机数与存储在ePass中的密钥进行HMAC-MD5运算并得到一个结果作为认证证据传给服务器(此为响应)。

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

安全性:

HMAC算法更象是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的HASH算法

1. 使用的密钥是双方事先约定的,第三方不可能知道。能够得到的信息只有作为“挑战”的随机数和作为“响应”的HMAC结果,无法根据这两个数据推算出密钥。由于不知道密钥,所以无法仿造出一致的响应。

2. HMAC与一般的加密重要的区别在于它具有“瞬时”性,即认证只在当时有效

HMAC Detail

Hmac算法(转) (2006-07-05 21:44)

组织:中国互动出版网(http://www.china-pub.com/
RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook.htm
E-mail:moc.bup-anihc|gnayuo#moc.bup-anihc|gnayuo
译者:马 良 (idayang ten.362|seliwrepus#ten.362|seliwrepus
译文发布时间:2001-8-7
版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但必须
保留本文档的翻译及版权信息。

Network Working Group R. Glenn
Request for Comments: 2104 NIST
Category: Standards Track S. Kent
BBN Corp
November 1998
HMAC:键入-散列法用于信息身份验证
(RFC2104—HMAC: Keyed-Hashing for Message Authentication)

本备忘录的状态
本文档讲述了一种Internet社区的Internet标准跟踪协议,它需要进一步进行讨论和建
议以得到改进。请参考最新版的“Internet正式协议标准” (STD1)来获得本协议的标准化程
度和状态。本备忘录的发布不受任何限制。
版权声明
Copyright (C) The Internet Society (1998). All Rights Reserved.

摘要:
本文档阐述了一种使用散列函数加密的消息验证机制——散列消息鉴别码
HMAC。HMAC通过捆绑一个共享密钥可以使用任何迭代的可用于加密的散列
函数。例如:MD5, SHA—1。这种加密机制的强度取决于所用散列函数的特性。

1. 简介 2
2. HMAC的定义。 2
3. 密钥。 3
4. 注意事项 4
5. 删节输出结果 4
6. 安全 4
注释: 5
附录: 5
致谢: 8
参考书目: 8

1. 简介
在开放的计算与通讯世界中,提供一种途径去检测通过不可靠媒介传输或
存储的信息完整性是非常重要的。提供这种完整性检测的机制基于一种通常
被称作消息鉴别码的密钥MAC。一般的,消息鉴别码用于验证传输于两个共
同享有一个密钥的单位之间的消息。在本文档中,我们将描述一种基于散列函数
的消息鉴别码机制。这种机制被称为散列消息鉴别码HMAC。它是基于[BCK1]
的作者所做的工作,他说明并就加密性能分析了HMAC的结构。我们在讲述H
MAC的基本原理和安全性分析时会提到这些结果,并且还要与其他键入式散列方
法做对比。
HMAC可以与任何迭代散列函数捆绑使用。MD5和SHA—1就是这种散列函数
HMAC还可以使用一个用于计算和确认消息鉴别值的密钥。
这种结构的主要作用是:

? 不用修改就可以使用适合的散列函数。而且散列函数在软件方面表现的很好。
并且源码是公开和通用的。

? 可以保持散列函数原有的性能而不致使其退化。

? 可以使得基于合理的关于底层散列函数假设的消息鉴别机制的加密强度分析
便于理解。

? 当发现或需要运算速度更快或更安全的散列函数时,可以很容易的实现底层
散列函数的替换。

本文档详细描述了HMAC使用一种抽象的散列函数(用H表示)。具体的HMAC
需要定义一个具体的散列函数。目前,可供选择的散列函数有SHA—1[SHA],MD5,
RIPEMD—128/160[RIPEMD]。这些不同的HMAC实现被表示为,HMAC—SHA1,
HMAC—MD5,HMAC—RIPEMD,等等。

注释:
在写本文档时,MD5和SHA—1是使用最广泛的加密用散列函数。MD5最近已被
证明对于[Dobb]的攻击存在缺陷。这种攻击方法和其他目前已知的MD5的缺陷不允许
在HMAC中按本文的方法使用MD5(细节请见[Dobb])。然而,SHA—1似乎是一种
更强壮的函数。目前,MD5 可以被考虑用于HMAC来为应用程序提供出众的执行效
率的观点受到批评。无论如何,执行者与用户都需要了解关于加密用散列函数被破解
可能性的最新进展,并可能会需要替换底层的散列函数。(关于HMAC安全性的更多
信息参见第六部分)

2. HMAC的定义。
定义HMAC需要一个加密用散列函数(表示为H)和一个密钥K。我们假设H是
一个将数据块用一个基本的迭代压缩函数来加密的散列函数。我们用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=60字节,则K后会加入44个零字节0x00)

(2) 将上一步生成的B字长的字符串与ipad做异或运算。

(3) 将数据流text填充至第二步的结果字符串中。

(4) 用H作用于第三步生成的数据流。

(5) 将第一步生成的B字长字符串与opad做异或运算。

(6) 再将第四步的结果填充进第五步的结果中。

(7) 用H作用于第六步生成的数据流,输出最终结果

基于MD5的相关代码将作为附录提供

3. 密钥。
用于HMAC的密钥可以是任意长度(比B长的密钥将首先被H处理)。但当密钥
长度小于L时的情况时非常令人失望的,因为这样将降低函数的安全强度。长度大于
L的密钥是可以接受的,但是额外的长度并不能显著的提高函数的安全强度。(如果一
个随机的密钥被认为是不可靠的,那么选择一个较长的密钥是明智的)。
密钥必须随机选取(或使用强大的基于随机种子的伪随机生成方法),并且要周期
性的更新。(目前的攻击没有指出一个有效的更换密钥的频率,因为那些攻击实际上并
不可行。然而,周期性更新密钥是一个对付函数和密钥所存在的潜在缺陷的基本
的安全措施,并可以降低泄漏密钥带来的危害。)

4. 注意事项
HMAC是按底层散列函数可以不修改源码就可使用这种方式定义的。尤其是它在使用
H函数时还要依赖于预定义的初始化值IV(一个定值,由每个迭代散列函数在初始化它
的压缩函数时指定).然而,如果你愿意的话,可以修改H函数的源码来支持可变的初始
化值Ivs.
这个想法是这样的:压缩函数作用于B字长数据块(K XOR opad)和(K XOR ipad)
所产生的中间结果可以在密钥刚刚生成时就预先计算好的。先将这些中间结果存储,然
后在每次有消息需要验证时来生成H函数的初始化值IV。这种方法为每个要鉴别的消息
保存了H 的压缩函数对于两个B字长数据块(K XOR opad)和(K XOR ipad)的应用。
当鉴别短数据流,保存这样的信息是重要的。我们要强调的是:对待这些中间结果要象
对待密钥一样,并且要同样的进行保密。
上述的选择实现HMAC的方法是本地执行的结果,对内部操作性没有影响。

5. 删节输出结果
一个著名的消息鉴别方法是删节消息鉴别码的输出,而只输出部分结果。Preneel
与Van Oorschot[pv]给出了一些散列消息鉴别码删节后的输出结果的优势分析。在这
一领域的成果并不是绝对的说删节输出结果有全面的安全优势。它有优势的一面(对一
个攻击者来说可用的散列函数结果信息将更少),也有劣势的一面(攻击者要预测的字长
更短)。基于HMAC的应用程序可以只输出HMAC计算结果的最左的t个字节(也就是说
,计算将按第二部分定义的方式执行,但输出结果将删节至t个字节)。我们推荐的输
出长度t不小于散列函数输出长度的一半(匹配生日攻击的限度)且不能少于80字节
(一个适合的速度限制的字节数使得攻击者难以去预测)。我们建议使用HMAC-H-t来表
示基于输出长度为t的散列函数的HMAC的实现。例如,HMAC-SHA1-80表示HMAC使用
SHA-1函数并且输出被删节至80字节。(如果没有声明这项参数,则假定不删节输出结
果。)
6. 安全
这里将说明消息鉴别机制的安全性取决于所采用的散列函数的加密特性:1。抗冲突
攻击能力(只限于初始化值是随机且秘密的,且函数的输出对攻击者来说是不可用的情
况)2。当作用于单数据块时H的压缩函数的的消息鉴别属性(在HMAC中这些数据块是
部分未知得,当攻击者自制内部H函数计算结果,并且攻击者是不能充分的选择得)
HMAC中使用的散列函数一般都具有以上或更强的属性。实际上,如果一个散列函数
不具有以上的属性那么它对于大多数的加密应用程序是不适用的,包括基于该函数的选
择消息鉴别方案。(对HMAC函数原理详细阐述和完整的分析参见[BCK1])
只要得到关于候选散列函数的加密强度有限的信任,那么观察它用于消息鉴别的安
全性及以下HMAC结构的两种属性是很重要的。
1. 这种结构是独立于具体所使用的散列函数并且后者是可以被任何其它安全加
密散列函数替代
2. 消息鉴别相对于加密来说是一种“瞬时”影响。公开的对一种消息鉴别方案
的破坏会导致该方案被替换,但是其对已鉴别过的信息却无能为力,。这就与
加密形成鲜明对比。如果其加密算法被破解的话。今天加密的的数据,在未
来都会受到被破解的威胁,
对HMAC已知最有力的攻击是基于散列函数的冲突频率。(“生日攻击法”)[PV,BCK2],
但完全不适用于最小有理散列函数。
例如:如果我们考虑一个类似MD5的散列函数,其输出结果长度为L=16字节(128
比特),攻击者需要获得正确的消息鉴别标志(使用相同的密钥K!!)计算大约264已
知明文。这样至少要使用H处理2
64数据块,这是一个不可能完成的任务(一个数据
块的长度为64字节,在连续的1Gbps link的条件下需要250,000年,并且在整个过程
中不能更换密钥!)这样的攻击只有在函数H的冲突行为的严重缺陷被发现才有可能成为
现实(冲突在处理2**30后会存在)。这样的发现会导致立即更换现有的函数H(这种故
障产生的影响远远大于传统的在上下文环境数字签名与公开密钥中使用的散列函数故
障。)

注释:
这种攻击与在无相关密钥、264离线并行计算可以发现冲突的环境中针对加密散
列函数的规则冲突攻击形成鲜明对比。在现在的条件下生日攻击已基本不可行, 而
后者可行性却很高。(在以上的例子中,如果使用的散列函数的输出是160字节,则
2
64应改为2**80)

正确的实施以上的结构时需要注意:选择随机(或加密的伪随机)密钥、一个安全
的密钥交换机制,频繁的更新密钥,对密钥的良好的安全防护。以上这些都是维护HMAC
完整的鉴别机制安全的基本要素。

附录:
例程源码
为了更好的说明该机制,我们提供了实现HMAC-MD5的源码,并且还提供了
一些相应的测试向量。(代码是基于[MD5]中的MD5的源码)

      /*
** Function: hmac_md5
*/
 
void
hmac_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

http://stamen.iteye.com/blog/1558255

http://baike.baidu.com/view/1136366.htm