HMac基本介绍
基本介紹
HMAC(散列消息身份驗證碼: Hashed Message Authentication Code)
它不是散列函數,而是采用散列函數(MD5 or 或SHA)與共享密鑰一起使用的消息身份驗證機制。
詳細見 RFC 2104
使用場景
服務端生成key,傳給客戶端;
客戶端使用key將帳號和密碼做HMAC,生成一串散列值,傳給服務端;
服務端使用key和數據庫中用戶和密碼做HMAC計算散列值,比對來自客戶端的散列值。
按照散列函數的不同,可以有如下實現。
Hmac_MD5,Hmac_sha1,Hmac_sha224,Hmac_sha256,Hmac_sha384,Hmac_sha512。
Hmac_MD5:
/**
* MD5(Key XOR opad, MD5(Key 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(maybe user or password).
*/
memcpy( k_ipad, key, key_len);
memcpy( k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner MD5
MD5Init(&context); /* init context for 1st pass */
MD5Update(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
MD5Update(&context, (unsigned char*)text, text_len); /* then text of datagram */
MD5Final(hmac, &context); /* finish up 1st pass */
// perform outer MD5
MD5Init(&context); /* init context for 2nd pass */
MD5Update(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
MD5Update(&context, hmac, MD5_DIGEST_SIZE); /* then results of 1st hash */
MD5Final(hmac, &context); /* finish up 2nd pass */
Hmac_sha1:
/**
* SHA(Key XOR opad, SHA(Key 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(maybe user or password).
*/
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner SHA
SHA_Init(&context); /* init context for 1st pass */
SHA_Bytes(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
SHA_Bytes(&context, text, text_len); /* then text of datagram */
SHA_Final(&context, hmac); /* finish up 1st pass */
// perform outer SHA
SHA_Init(&context); /* init context for 2nd pass */
SHA_Bytes(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
SHA_Bytes(&context, hmac, SHA1_DIGEST_SIZE); /* then results of 1st hash */
SHA_Final(&context, hmac); /* finish up 2nd pass */
Hmac_sha224,mac_sha256 和Hmac_sh啊類似,把SHA換成SHA224或SHA256即可,注意 ipad和opad的長度為64.
Hmac_sha384:Hmac_sha512和Hmac_sha384類似,把SHA384換成SHA512即可,注意 ipad和opad的長度為128.
/**
* SHA384(Key XOR opad, SHA(Key XOR ipad, text))
*
* where K is an n byte key
* ipad is the byte 0x36 repeated 128 times
* opad is the byte 0x5c repeated 128 times
* and text is the data being protected(maybe user or password).
*/
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < KEY_IOPAD_SIZE128; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner SHA384
SHA384_Init(&context); /* init context for 1st pass */
SHA384_Bytes(&context, k_ipad, KEY_IOPAD_SIZE128); /* start with inner pad */
SHA384_Bytes(&context, text, text_len); /* then text of datagram */
SHA384_Final(&context, hmac); /* finish up 1st pass */
// perform outer SHA384
SHA384_Init(&context); /* init context for 2nd pass */
SHA384_Bytes(&context, k_opad, KEY_IOPAD_SIZE128); /* start with outer pad */
SHA384_Bytes(&context, hmac, SHA384_DIGEST_SIZE); /* then results of 1st hash */
SHA384_Final(&context, hmac); /* finish up 2nd pass */
C implement at github:https://github.com/mygityf/cipher/blob/master/cipher/hmac.c
Done.
總結
- 上一篇: fopen函数打开文件总是返回NULL错
- 下一篇: ETM and PTM