引言

最近手头有个项目涉及到HMAC消息认证算法,要求基于国密算法SM3和C实现,即HMAC-SM3; 网上查资料:HMAC-MD5/HMAC-SHA等一大堆java/python的可用接口,却很少看到基于C语言实现的,若是再加上SM3的算法,更是少之又少; 于是乎,自己撸了一个,权当心得记录;

1 何为SM3算法?

相信很多同学听过MD5算法,但听过SM3算法估计会比较少,因为涉及到行业领域;

  • MD5是一种摘要算法:输入任意长度的信息,经过摘要处理,输出为128位(16字节)数据。(别称:数字指纹);

  • SM3算法是国密算法中的一种,对标的是MD5算法;(另外,SM2对标RSA算法,SM4对标DES算法,ZF要求银行等金融领域均改造成国密算法); SM3输出的摘要值为256位(32字节),其安全性更高于MD5;

2 何为HMAC算法?

​ HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写; 基于MD5/SM3等摘要算法,多融入了一个Key(秘钥数组);HMAC计算得到的完整摘要值与原摘要算法计算的一致;

3 为何要用HMac算法?

​ 以MD5为例展开,比如通过某个镜像网站下载一个文件,下载完成后可通过本地MD5对下载的文件计算MD5值,与该网站上同文件显示的MD5值比对,一不一致就很清楚了。这是不同渠道,各自计算摘要值进行比对的案例场景;
​ 如果要通过同一个渠道发送数据和Hash值的话(比如消息认证码),就要考虑数据和MD5同时被篡改的问题;如果第三方修改了数据,然后进行MD5 Hash,并一块发给接收方,接收方并不能察觉到数据被篡改。
​ HMAC-MD5就可以用一把发送方和接收方都有的key进行计算,而没有这把key的第三方是无法计算出正确的Hash的,这样就可以防止数据被篡改。

4 HMAC算法流程

​ 以下基于HMAC-SM3说明HMAC的算法流程(其余摘要算法替换掉SM3即可):

​ 在HMAC的定义中用到一个密码散列函数和一个密钥Key。本说明中使用SM3作为对明文进行分组循环压缩的散列函数,明文分组长度为64(byte),散列函数的输出长度为32(byte)。认证密钥K为随机生成。
再定义两个不同的固定字符串iPad和oPad如下("i"和"o"表示内部和外部):
再定义两个不同的固定字符串iPad和oPad如下("i"和"o"表示内部和外部):
​ ●iPad=一个字节(byte)的 0x36重复64次;
​ ●oPad=- 一个字节(byte)的0x5C重复64次

操作步骤如下:
1.在密钥K后面填充0,使其成为长度为64byte的字符串。
2.用第一步得到的 64byte的字符串与iPad作按位异或;
3.将消息Message附加到第二步产生的64byte字符串后面;
4.对第三步产生的数据流用散列函数SM3计算消息摘要;
5.用第一步得到的 64byte的字符串与oPad作按位异或:
6.将第四步生成的消息摘要附加到第五步的64byte字符串之后:
7.对第六步产生的数据流用散列函数SM3计算消息摘要,作为输出

以输入Message为例,作如下操作: H(K XOR oPad, H(K XOR iPad, Message))
其中H为哈希函数,也就是我们,上面的SM3;

5 HMAC-SM3基于C的代码实现

/*
========================================================================
Routine Description:HMAC using SM3 hash function
Arguments:key             Secret keykey_len         The length of the key in bytesmessage         Message contextmessage_len     The length of message in bytesmacLen          Request the length of message authentication code
Return Value:mac             Message authentication code
Note:None
========================================================================
*/
int HMAC_SM3(IN  UINT8 Key[],IN  UINT KeyLen,IN  const UINT8 Message[],IN  UINT MessageLen,OUT UINT8 MAC[],IN  UINT MACLen)
{UINT8 K0[SM3_BLOCK_SIZE];UINT8 Digest[SM3_DIGEST_SIZE];UINT index;UINT  ret;UINT8  *p_hmac_sm3_data=NULL;UINT hmac_sm3_data_len=0;UINT8 tmp_buf[SM3_BLOCK_SIZE+SM3_DIGEST_SIZE]={0};/** If the length of K = B(Block size): K0 = K.* If the length of K > B: hash K to obtain an L byte string,* then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).* If the length of K < B: append zeros to the end of K to create a B-byte string K0*/NdisZeroMemory(K0, SM3_BLOCK_SIZE);if (KeyLen <= SM3_BLOCK_SIZE) {NdisMoveMemory(K0, Key, KeyLen);} else {    ret=mh_sm3(K0, Key, SM3_DIGEST_SIZE);if(ret!=MH_RET_SM3_SUCCESS){return RETURN_FAIL;    }}/* Exclusive-Or K0 with ipad *//* ipad: Inner pad; the byte x锟斤拷36锟斤拷 repeated B times. */for (index = 0; index < SM3_BLOCK_SIZE; index++)K0[index] ^= 0x36;/* End of for */hmac_sm3_data_len=sizeof(K0)+MessageLen;p_hmac_sm3_data = (unsigned char *)malloc(hmac_sm3_data_len);if(NULL == p_hmac_sm3_data){return RETURN_FAIL;  }NdisMoveMemory(p_hmac_sm3_data,K0,sizeof(K0));NdisMoveMemory(p_hmac_sm3_data+sizeof(K0),Message,MessageLen);ret=mh_sm3(Digest, p_hmac_sm3_data, hmac_sm3_data_len);if(ret!=MH_RET_SM3_SUCCESS){free(p_hmac_sm3_data);p_hmac_sm3_data = NULL;return RETURN_FAIL;   }/* Exclusive-Or K0 with opad and remove ipad *//* opad: Outer pad; the byte x锟斤拷5c锟斤拷 repeated B times. */for (index = 0; index < SM3_BLOCK_SIZE; index++)K0[index] ^= 0x36^0x5c;/* End of for */NdisMoveMemory(tmp_buf,K0,sizeof(K0));NdisMoveMemory(tmp_buf+sizeof(K0),Digest,sizeof(Digest));ret=mh_sm3(Digest, tmp_buf, sizeof(tmp_buf));if(ret!=MH_RET_SM3_SUCCESS){free(p_hmac_sm3_data);p_hmac_sm3_data = NULL;return RETURN_FAIL;   }free(p_hmac_sm3_data);p_hmac_sm3_data = NULL;if (MACLen > SM3_DIGEST_SIZE)NdisMoveMemory(MAC, Digest, SM3_DIGEST_SIZE);elseNdisMoveMemory(MAC, Digest, MACLen);return RETURN_SUCC;
} /* End of HMAC_SHA256 */

6 需要完整HMAC-SM3的C源码的同学可在公众号发送关键字"SM3"获取

基于C实现HMAC-MD5和HMAC-SM3相关推荐

  1. MD5 SHA1 HMAC HMAC_SHA1区别(转载网上大牛)个人备忘和加注了

    MD5 SHA1 HMAC HMAC_SHA1区别 什么是MD5,什么是SHA1,如何校验这些Hash.还有拿单个apk文件的MD5,SHA1讯问是不是原版的问题,在这里,让我们先来了解一些基本知识, ...

  2. 基于Hash的消息认证码HMAC简介及在OpenSSL中使用举例

    HMAC(Hash-based Message Authentication Code):基于Hash的消息认证码,是一种通过特别计算方式之后产生的消息认证码(MAC),使用密码散列函数,同时结合一个 ...

  3. MD5 SHA1 HMAC HMAC_SHA1区别

    MD5是一种不可逆的加密算法,目前是最牢靠的加密算法之一,尚没有能够逆运算的程序被开发出来,它对应任何字符串都可以加密成一段唯一的固定长度的代码. SHA1是由NISTNSA设计为同DSA一起使用的, ...

  4. hmac hmac.new_使用HMAC(Play 2.0)保护REST服务

    hmac hmac.new 我们有HTTPS,还需要什么? 当您谈论基于REST的API的安全性时,人们通常会指向HTTPS. 借助HTTPS,您可以使用每个人都熟悉的方法轻松保护您的服务免遭窥视. ...

  5. 基于java注册登录MD5算法加盐加密颁发 Token身份令牌使用各种邮箱发送验证码详解雪花算法

    目的作用 == 在项目中,为了防止别人窥视我们的密码通常我们会采取一些加密方式.这里简单介绍一下MD5 加盐加密方法,MD5叫做信息-摘要算法,严格来说不是加密方式,而是信息摘要. 对于可以接触到数据 ...

  6. hmac java_java 创建 HMAC 签名

    ava 创建 HMAC 签名 1. []ComputopTest.java package com.javaonly.hmac.test; import java.io.IOException; im ...

  7. 基于流式的md5计算-多线程下载工具Lwget介绍

    在数据传输的时候,我们希望实现以下目标: 1. 使用多线程传输,加速下载速度 2. 数据在传输过程中,进行流式md5计算,避免在传输完毕之后校验大文件 3. 支持断点续传 4. 支持http协议和ft ...

  8. 基于Java实现的MD5算法实现

    MD5 算法实现 一.算法原理概述 MD5 即 MD5 Message-Digest Algorithm(MD5 消息摘要算法). MD4 (1990).MD5(1992, RFC 1321) 由 R ...

  9. java md5加密64位_基于Java语言的MD5加密Base64转换方法

    1 importjava.io.IOException;2 importjava.math.BigInteger;3 importjava.security.MessageDigest;4 impor ...

  10. Java 密码学相关知识

    密码的发展 密码的起源: 密码的起源非常早,早期的符号密码像宗教符号.岩壁画,至今无人破解的"费托斯圆盘"和无人读懂的"伏尼契手稿" 古代隐写术: 国内的:封蜡 ...

最新文章

  1. 老男孩Linux运维第41期20170924开班第五周学习重点课堂记录
  2. 如何查询土地规划用途_一秒辨别“三无产品”,护肤品的猫腻如何发现?
  3. CUDA系列学习(四)Parallel Task类型 与 Memory Allocation
  4. C语言程序设计二期末考试,9第二学期期末考试《C语言程序设计》A
  5. 使用 Web Tracing Framework 分析富 JS 应用的性能
  6. AC+AP组网和MESH组网介绍和区别
  7. struct/class等内存字节对齐问题详解
  8. No package ‘libpeas-1.0‘ found/No package ‘libpeas-gtk-1.0‘
  9. Jni 返回jstring字符串
  10. php调用winhttp,HTTP HTTPS POST GET(包含curl版本和winhttp两种实现)
  11. python numpy计算任意底数的对数 log
  12. 软件工程pert图_《软件工程》软件项目管理实验
  13. LoadRunner视频教程
  14. 笔记本电脑频繁自动重启_笔记本电脑频繁自动重启的原因和纠正
  15. PS4 从局域网安装PS4 PKG游戏 | PS4 HEN PS4 Package Sender
  16. 2022快速计算机视觉EI国际会议汇总
  17. 基于MATLAB的人民币识别系统
  18. 利用UE简化JAVA后端的SQL语句编辑
  19. Google浏览器Chrome正式发布
  20. c语言 url字符串解析,c语言截取下载url中文件名称

热门文章

  1. 从三层架构说起,谈谈对历史项目的小改造
  2. 工控安全入门之工业设备PLC
  3. c#类属性和实例属性_实例|EPS输出的CASS数据,房屋属性错误怎么解决? 111
  4. 数据化和人工智能 新零售要来了
  5. 全球及中国商业保理行业融资规模现状与盈利价值分析报告2022-2028年
  6. 基于Qt的组态监控软件实现以及分析(转)
  7. 惠普打印机介质不匹配_HP打印机安装驱动时提示“重要!选择与打印机的连接方式”解决方法...
  8. GridView ItemTemplate 格式
  9. 我的世界1.13 mod制作——环境搭建(一)
  10. 简体繁体英文国家名称切换