MAC(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥。因此MAC算法也经常被称作HMAC算法。

1HMAC概述

HMAC算法首先它是基于信息摘要算法的。目前主要集合了MD和SHA两大系列消息摘要算法。其中MD系列的算法有HmacMD2、HmacMD4、HmacMD5三种算法;SHA系列的算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512五种算法。

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

2HMAC算法分析

HMAC算法本身并不复杂,起需要有一个哈希函数,我们记为H。同时还需要有一个密钥,我们记为K。每种信息摘要函数都对信息进行分组,每个信息块的长度是固定的,我们记为B(如:SHA1为512位,即64字节)。每种信息摘要算法都会输出一个固定长度的信息摘要,我们将信息摘要的长度记为L(如MD5为16字节,SHA-1为20个字节)。正如前面所述,K的长度理论上是任意的,一般为了安全强度考虑,选取不小于L的长度。

HMAC算法其实就是利用密钥和明文进行两轮哈希运算,以公式可以表示如下:

HMAC(K,M)=H(K⊕opad∣H(K⊕ipad∣M)),其中:

Ipad为0x36重复B次

Opad为0x5c重复B次

M 代表一个消息输入

根据上面的算法表示公式,我们可以描述HMAC算法的运算步骤:

(1)、检查密钥K的长度。如果K的长度大于B则先使用摘要算法计算出一个长度为L的新密钥。如果后K的长度小于B,则在其后面追加0来使其长度达到B。

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

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

(4)、使用哈希函数H计算上一步中生成的数据流的信息摘要值。

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

(6)、再将第四步得到的结果填充到第五步的结果之后。

(7)、使用哈希函数H计算上一步中生成的数据流的信息摘要值,输出结果就是最终的HMAC值。

由上述描述过程,我们知道HMAC算法的计算过程实际是对原文做了两次类似于加盐处理的哈希过程。

3、代码实现

前面我们描述了HMAC算法及其实现过程,接下来我们则将其实现。首先我们定义一个用于保存计算过程上下文的结构:

/** 该结构将为HMAC密钥哈希操作保存上下文信息*/

typedef struct HMACContext {

int whichSha; /* 所用的SHA算法 */

int hashSize; /* 所用SHA的哈希值大小 */

int blockSize; /* 所用SHA块的大小 */

SHAContext shaContext; /* SHA上下文 */

unsigned char k_opad[SHA_Max_Message_Block_Size];/* outer padding - key XORd with opad */

int Computed; /* Is the MAC computed? */

int Corrupted; /* Cumulative corruption code */

} HMACContext;

接下来实现HMAC初始化函数。这个函数将初始化hmacContext以准备计算一个新的HMAC消息摘要。

int hmacReset(HMACContext *context, enum SHAversion whichSha,const unsigned char *key, int key_len)

{

int i, blocksize, hashsize, ret;

unsigned char k_ipad[SHA_Max_Message_Block_Size];/* inner padding - key XORd with ipad */

unsigned char tempkey[SHAMaxHashSize];/* temporary buffer when keylen > blocksize */

if (!context) return shaNull;

context->Computed = 0;

context->Corrupted = shaSuccess;

blocksize = context->blockSize = SHABlockSize(whichSha);

hashsize = context->hashSize = SHAHashSize(whichSha);

context->whichSha = whichSha;

/*如果键长于哈希块大小,将其重置为key = hash (key)。 */

if (key_len > blocksize) {

SHAContext tcontext;

int err = SHAReset(&tcontext, whichSha) ||

SHAInput(&tcontext, key, key_len) ||

SHAResult(&tcontext, tempkey);

if (err != shaSuccess) return err;

key = tempkey;

key_len = hashsize;

}

/*将key与ipad和opad按位异或*/

for (i = 0; i < key_len; i++) {

k_ipad[i] = key[i] ^ 0x36;

context->k_opad[i] = key[i] ^ 0x5c;

}

/*将key填充0直到blocksize并与ipad和opad按位异或 */

for ( ; i < blocksize; i++) {

k_ipad[i] = 0x36;

context->k_opad[i] = 0x5c;

}

/* 开始内层哈希运算 */

ret = SHAReset(&context->shaContext, whichSha) ||

SHAInput(&context->shaContext, k_ipad, blocksize);

return context->Corrupted = ret;

}

接下来输入将要处理的信息,这个函数接受一个字节数组作为消息的下一处理部分。

int hmacInput(HMACContext *context, const unsigned char *text,int text_len)

{

if (!context) return shaNull;

if (context->Corrupted) return context->Corrupted;

if (context->Computed) return context->Corrupted = shaStateError;

/* 报文内容 */

return context->Corrupted =SHAInput(&context->shaContext, text, text_len);

}

最后处理完成全部过程,返回信息摘要。此函数将返回相应大小的消息摘要,具体是多长的信息摘要由具体的SHA算法决定。

int hmacResult(HMACContext *context, uint8_t *digest)

{

int ret;

if (!context) return shaNull;

if (context->Corrupted) return context->Corrupted;

if (context->Computed) return context->Corrupted = shaStateError;

/* 完成内层哈希运算 */

ret =SHAResult(&context->shaContext, digest) ||

/* 执行外层哈希运算 */

SHAReset(&context->shaContext, context->whichSha) ||

SHAInput(&context->shaContext, context->k_opad,context->blockSize) ||

SHAInput(&context->shaContext, digest, context->hashSize) ||

SHAResult(&context->shaContext, digest);

context->Computed = 1;

return context->Corrupted = ret;

}

4、结果

我们已经实现了HMAC算法,接下来我们对其进行验证。我们采用简单的测试,取加密文本为text =“abcd”,设密钥为key=“123456”,基于SHA-1的HMAC运算结果如下:

基于SHA-256的HMAC运算结果如下:

基于SHA-512的运算结果如下:

我们测试了HMAC-SHA1、HMAC-SHA256、HMAC-512三种情况,与在线HMAC加密算法进行对比计算,记过完全一致。

欢迎关注:

信息摘要算法之五:HMAC算法分析与实现的更多相关文章

  1. 信息摘要算法之一:MD5算法解析及实现

    MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致.是计算机广泛使用的杂凑算法之一(又译摘要算法.哈希算法),主流编程语言普遍已有MD5实现. ...

  2. 信息摘要算法 MessageDigestUtil

    package com.xgh.message.digest.test; import java.math.BigInteger; import java.security.MessageDigest ...

  3. MD5加密算法(信息摘要算法)、Base64算法

    1 什么是MD5 信息摘要算法,可以将字符进行加密,每个加密对象在进行加密后都是等长的 应用场景:将用户密码经过MD5加密后再存储到数据库中,这样即使是超级管理员也没有能力知道用户的具体密码是多少:因 ...

  4. MD5( 信息摘要算法)的概念原理及python代码的实现

    简述: message-digest algorithm 5(信息-摘要算法).经常说的“MD5加密”,就是它→信息-摘要算法. md5,其实就是一种算法.可以将一个字符串,或文件,或压缩包,执行md ...

  5. OpenSSL实现了5种信息摘要算法有哪些?

    OpenSSL实现了5种信息摘要算法,分别是MD2.MD5.MDC2.SHA(SHA1)和RIPEMD.SHA算法事实上包括了SHA和SHA1两种信息摘要算法.此外,OpenSSL还实现了DSS标准中 ...

  6. 信息摘要算法之六:HKDF算法分析与实现

    HKDF是一种特定的键衍生函数(KDF),即初始键控材料的功能,KDF从其中派生出一个或多个密码强大的密钥.在此我们想要描述的是基于HMAC的HKDF. 1.HKDF概述 密钥派生函数(KDF)是密码 ...

  7. 信息摘要算法之三:SHA256算法分析与实现

    前面一篇中我们分析了SHA的原理,并且以SHA1为例实现了相关的算法,在这一片中我们将进一步分析SHA2并实现之. 1.SHA简述 前面的篇章中我们已经说明过,SHA实际包括有一系列算法,分别是SHA ...

  8. 信息摘要算法之四:SHA512算法分析与实现

    前面一篇中我们分析了SHA256的原理,并且实现了该算法,在这一篇中我们将进一步分析SHA512并实现之. 1.SHA简述 尽管在前面的篇章中我们介绍过SHA算法,但出于阐述的完整性我依然要简单的说明 ...

  9. 信息摘要算法之二:SHA1算法分析及实现

    SHA算法,即安全散列算法(Secure Hash Algorithm)是一种与MD5同源的数据加密算法,该算法经过加密专家多年来的发展和改进已日益完善,现在已成为公认的最安全的散列算法之一,并被广泛 ...

随机推荐

  1. Coursera, Deep Learning 4, Convolutional Neural Networks - week1

    CNN 主要解决 computer vision 问题,同时解决input X 维度太大的问题. Edge detection 下面演示了convolution 的概念 下图的 vertical ed ...

  2. AttributeError: module '__main__' has no attribute 'main'解决方法

    在终端运行.py文件时报错:AttributeError: module '__main__' has no attribute 'main' 原因:在PyCharm里运行python程序需要添加 i ...

  3. Spark思维导图之Spark Streaming

  4. CentOS7.2卸载完CDH5.12后重装CDH

    1因为是重装很多环境ok A mysql环境ok B 防火墙ok C hostname绑定也没有问题 D jdk也是ok E root用户,所以不涉及权限,如果不是请设置sudo权限用户    F n ...

  5. Http 持久连接与 HttpClient 连接池

    一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...

  6. 阿里前CEO卫哲:马云好玩,人工智能泡沫巨大,新零售重在社区

    阿里前CEO卫哲:马云好玩,人工智能泡沫巨大,新零售重在社区 投资中国网 08-21 08:34 投中网(https://www.chinaventure.com.cn) 编者按:当下的技术时代,是跨 ...

  7. vue 学习笔记—Resource

    1.首先是引入  或者用npm来安装  cnpm i vue-resource --save(推荐) 3.提供的api 关于请求写法: get(){ // get请求 this.$http.get( ...

  8. SQL操作json类型数据的函数

    MySQL5.7之后对json数据格式进行了函数支持 Json_contains(字段名, '值') 1.表中json格式的某个字段 2.json里的某个键值 Json_search(字段名, 'on ...

  9. 超级简单的Android Studio jni 实现(无需命令行)【转载】

    原文: http://www.jianshu.com/p/e689d0196a17 1.配置Anroid Studio(这步是关键) 使用[command+,] 打开Preferences,选择Ext ...

  10. 快速搭建ELK日志分析系统

    一.ELK搭建篇 官网地址:https://www.elastic.co/cn/ 官网权威指南:https://www.elastic.co/guide/cn/elasticsearch/guide/ ...