流行算法:HMAC算法 - 网上购物、转账、炒股等没她不行

admin 2024-11-21 251人围观 ,发现72个评论
一、定义

HMAC(Hash-BasedMessageAuthenticationCode)由,和于1996年提出的一种基于Hash函数和密钥进行消息认证的方法,并于1997年作为RFC2104被公布,并在IPSec和其他网络协议(如SSL)中得以广泛应用,现在已经成为事实上的Internet安全标准。它可以与任何迭代散列函数捆绑使用。

HMAC算法除了需要消息摘要算法外,还需要一个密钥。HMAC的密钥可以是任何长度,如果密钥的长度超过了摘要算法信息分组的长度,则首先使用摘要算法计算密钥的摘要作为新的密钥。一般不建议使用太短的密钥,因为密钥的长度与安全强度是相关的。通常选取密钥长度不小于所选用摘要算法输出的信息摘要的长度。

HMAC认证,主要是为了能让人对对方身份正确性和消息有效性进行验证,与消息摘要的最大不同,就是有签名密钥。而摘要算法,只是能够证明消息的有效性。HMAC被广泛地运用于网络协议的认证阶段,例如邮件协议使用到了它,SSL也有它的身影。

二、举例理解

HMAC的核心思想是身份认证和消息有效性认证。

1、前提条件

在消息认证码生成的一方和校验的一方,必须有一个共同的秘钥。

双方约定好使用同样的哈希函数对数据进行运算。

2、流程

发送者:

发送原始法消息

将原始消息生成消息认证码:哈希函数(原始消息+秘钥)=散列值(消息认证码)

将消息认证码发送给对方

接收者:

接收原始数据

接收消息认证码

校验:哈希函数(接收的消息+秘钥)*哈希函数=散列值,将本地计算的散列值和接收的散列值进行比较。

三、HMAC算法表示

算法公式:
HMAC(K,Text)=H((K⊕opad)|H((K⊕ipad)|Text))
H代表所采用的HASH算法(如MD5、SHA1、SHA-256等)。
K代表认证密码。
Text代表一个消息输入。

⊕代表异或。

|表示两个消息合并。
Opad用0x5c重复填充大小为B的数组。
Ipad用0x36重复填充大小为B的数组。
Apad用0x878FE1F3重复(L/4)次。

B代表H中所处理的块大小,这个大小是处理块大小,而不是输出hash的大小。
如MD5、SHA-1和SHA-256对应B=64,SHA-384和SHA-512对应B=128。

L表示hash结果的大小,L=16forMD5,L=20forSHA-1。

C演示代码表示:

voidhmac_md5(text,text_len,key,key_len,digest)unsignedchar*text;/*pointertodatastream*/inttext_len;/*lengthofdatastream*/unsignedchar*key;/*pointertoauthenticationkey*/intkey_len;/*lengthofauthenticationkey*/unsignedchar*digest;/*output:digest*/{unsignedchartk[16];unsignedchark_ipad[64];/*innerpadding-*keyXORwithipad*/unsignedchark_opad[64];/*outerpadding-*keyXORwithopad*/MD5_CTXcontext;/*ifkeyislongerthan64bytesresetittokey=MD5(key)*/if(key_len64){MD5_CTXtctx;MD5Init(tctx);MD5Update(tctx,key,key_len);MD5Final(tk,tctx);key=tk;key_len=16;}/*startoutbystoringkeyinpads*/memset(k_ipad,0,sizeof(k_ipad));memset(k_opad,0,sizeof(k_opad));memcpy(k_ipad,key,key_len);memcpy(k_opad,key,key_len);/*XORkeywithipadandopadvalues*/for(inti=0;i64;i++){k_ipad[i]^=0x36;k_opad[i]^=0x5c;}/*performinnerMD5*/MD5Init(context);/*initcontextfor1stpass*/MD5Update(context,k_ipad,64)/*startwithinnerpad*/MD5Update(context,text,text_len);/*thentextofdatagram*/MD5Final(digest,context);/*finishup1stpass*//*performouterMD5*/MD5Init(context);/*initcontextfor2ndpass*/MD5Update(context,k_opad,64);/*startwithouterpad*/MD5Update(context,digest,16);/*thenresultsof1sthash*/MD5Final(digest,context);/*finishup2ndpass*/}
四、运算步骤

如果密钥K的长度大于B的字长,对密钥K计算hash(K),结果当作输入密钥;

在密钥K后面添加0来创建一个字长为B的字符串(例如,如果K的字长是20字节,B=64字节,则K后会加入44个零字节0x00);

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

将数据流text补充至第(3)步的结果字符串的尾部;

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

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

再将第(6)步的结果补充至第五步的结果的尾部;

用H作用于第(7)步生成的数据流,输出最终结果。
由上述描述过程,我们知道HMAC算法的计算过程实际是对原文做了两次类似于加盐处理的哈希过程。

HMAC的密钥长度可以是任意大小,如果小于n(hash输出值的长度),那么将会削弱算法安全的强度。建议使用长度大于n的密钥,但是采用长度大的密钥并不意味着增强了函数的安全性。密钥应该是随机选取的,可以采用一种强伪随机发生器,并且密钥需要周期性更新,这样可以减少弱密钥的危险性以及已经暴露密钥所带来的破坏。

五、计算结果演示

消息:ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

密钥:iloveyou

#

HMAC函数

计算结果

字节长度

1

Hmac-md2

62b22a645d7f331422b4d087e0558675

16

2

Hmac-md4

fbff23b3c9903291fdc5a00d410b77a8

16

3

Hmac-md5

79e44af262dc67cf7feefc2a08a2fda6

16

4

Hmac-sha1

ea1a4b8e9185f607ba02b9773cb7dadd736de12b

20

5

Hmac-sha256

8635a9cfa8c0f8569cb08b4268446df0c5a9088a407b25a09dd5f050bd0d5cf7

32

6

Hmac-sha512

4e9efe08ad0229636975e9f756c6802cce93e75adbfaacf94cad9bdf9dba35a9e3bdd42619bce98b6d4c118b8a7431bb9b15ea88ba26d8de365252c7308be39b

64

7

Hmac-sha224

5235a3edbc52ed72fb1cc3bb9d32745b56eaee4e91a056019ee75116

28

8

Hmac-sha384

15ae925c4dc725c155a5155c7877e0fd29b7dc6f2e811f2b0252112a7aa2fee3cf2ee40f8642805850862e0ffb601053

48

9

Hmac-sha3-224

9d53a512f6cc446734627cdea59057c254db3bbc7f490a35e680fd08

28

10

Hmac-sha3-256

df7cd9e4c124a764ae151694b2acae7cec0490a0ddeece8e9e76023afdbf5dbc

32

11

Hmac-sha3-384

4bb7e1eda41dd5b803b1bfbdf93070d757b18c6e18e759155bfd2fed5000ef4d4630b2d55ad2f0a6d18631b2c338c997

48

12

Hmac-sha3-512

bf8c6284396c6c3fab7bab7558109715ed40c9b8012391fd51c23f5c57143aa1aba7dd5e0a2106fbda3e0c4d547015aa2911ce9049201409bd618cd71b87b3e8

64

六、支持的散列函数

目前用来对消息进行认证的主要方式有2种:消息加密和消息认证码。

消息加密:它利用分组密码对整个消息加密,将密文作为认证符;

消息认证码:秘钥+散列函数。

消息认证码的方式比消息加密的方式计算速度更快,这对于高速网络业务处理来说,分秒必争。

消息认证码的关键是散列函数的选择,这就要在安全强度和速度两方面综合考虑。

HMAC算法首先它是基于消息摘要算法的,目前主要集合了MD和SHA两大系列消息摘要算法,其中MD系列的算法有HMAC-MD2、HMAC-MD4、HMAC-MD5三种算法;SHA系列的算法有HMAC-SHA1、HMAC-SHA224、HMAC-SHA256、HMAC-SHA384、HMAC-SHA512五种算法。

HMAC算法还支持大量的消息摘要算法:md5、sha1、sha256、sha512、adler32、crc32、crc32b、fnv132、fnv164、fnv1a32、fnv1a64、gost、gost-crypto、haval128,3、haval128,4、haval128,5、haval160,3、haval160,4、haval160,5、haval192,3、haval192,4、haval192,5、haval224,3、haval224,4、haval224,5、haval256,3、haval256,4、haval256,5、joaat、md2、md4、ripemd128、ripemd160、ripemd256、ripemd320、sha224、sha3-224、sha3-256、sha3-384、sha3-512、sha384、sha512/224、sha512/256、snefru、snefru256、tiger128,3、tiger128,4、tiger160,3、tiger160,4、tiger192,3、tiger192,4、whirlpool。

七、HMAC独特优势

与数字签名比较,HMAC并不完美,存在一个弊端和两个无法解决的问题。

弊端:秘钥分发困难。

无法解决的问题:不能进行第三方证明和不能防止否认。

理想往往败给现实,数字签名需要分发公钥与私钥,且签名验证速度慢,证书颁发还要到专门的机构申请和缴费。HMAC对密码的使用很处理比较简单,对于要求快速处理的业务来说,其好处的吸引力非常诱人。

而与分组密码认证相比,HMAC有几大优势:

一般的散列函数的软件执行速度比分组密码更快;

如果找到或需要更快或更安全的散列函数,能够很容易地代替原来嵌入的散列函数。

八、典型应用1、IPSec和SSL协议中的应用

HMAC算法广泛应用在在互联网的安全认证和安全传输中。

在浏览网页时,https开头的网址都是用到了SSL协议,用于保证网页内容的安全,这是由HMAC算法实现的。

2、API接口签名验证

我们在网上购物、买票、银行转账、炒股等都用到了HMAC算法。各大银行和BAT大厂的后台与前端都用到了API接口签名验证。

用户需要先在网站上申请key、secret,然后校验流程如下:

方法一参数方式

请求接口:;home=worldwork=java

客户端:

1生成当前时间戳timestamp=now和唯一随机字符串nonce=random;

2按照请求参数名的字母升序排列非空请求参数(包含accessKey)
stringA="home=worldname=hellowork=javaaccessKey=keytimestamp=nownonce=random";

3计算签名signature=HMAC-SHA256(secret,stringA);

4最终请求

;home=worldwork=javaaccessKey=keytimestamp=nownonce=noncesign=signature.

服务器:

1按照请求参数名的字母升序排列非空请求参数(包含accessKey)
stringB="home=worldname=hellowork=javaaccessKey=keytimestamp=nownonce=random";

2通过key在数据库获取secret;

3计算签名signature=HMAC-SHA256(secret,stringB);

4将signature与接收的签名串比较。

方法二请求体Body方式

客户端:

1将请求参数封装成json字符串,也就是请求体body;

2使用HMAC-SHA256算法加secret对Msg(请求url+timestamp+nonce+body)加密生成摘要signature;

3将key,signature放入header中一并传给服务器。


服务器:

1获取请求中的请求体body字符串;

2使用HMAC-SHA256算法加secret(通过header中的key在数据库获取)对Msg(请求url+timestamp+nonce+body)加密生成摘要signature;

3服务端生成的摘要串与客户端通过header传递过来的摘要串进行比较。

timestamp+nonce方案(防止重放攻击)

nonce指唯一的随机字符串,用来标识每个被签名的请求。通过为每个请求提供一个唯一的标识符,服务器能够防止请求被多次使用(记录所有用过的nonce以阻止它们被二次使用)。

假设允许客户端和服务端最多能存在15分钟的时间差,同时追踪记录在服务端的nonce集合。当有新的请求进入时,首先检查携带的timestamp是否在15分钟内,如超出时间范围,则拒绝,然后查询携带的nonce,如存在已有集合,则拒绝。否则,记录该nonce,并删除集合内时间戳大于15分钟的nonce(可以使用redis的expire,新增nonce的同时设置它的超时失效时间为15分钟)。

注意使用HMAC-SHA256更加安全,而且我们可以直接将请求参数封装成json字符串放入请求体中(也就是通过io流)进行传递。

方法三Token+AppKeyToken身份验证

1用户登录向服务器提供认证信息(如账号和密码),服务器验证成功后返回Token给客户端;

2客户端将Token保存在本地,后续发起请求时,携带此Token;

3服务器检查Token的有效性,有效则放行,无效(Token错误或过期)则拒绝。

为客户端分配AppKey(密钥,用于接口加密,不参与传输)

将所有请求参数组合成串,根据HMAC+AppKey签名算法生成签名值,发送请求时将签名值一起发送给服务器验证。这样,即使Token被劫持,对方不知道AppKey,就无法伪造请求和篡改参数。再结合重发攻击解决方案,即使请求参数被劫持也无法伪造二次重复请求。

3、客户端与服务器身份认证

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

猜你喜欢
    不容错过