HMAC原理及SM3-HMAC实现

HMAC原理

一、定义

MAC(Message Authentication Code,消息认证码算法),MAC是含有密钥的散列函数算法,因此也MAC算法也通常被称为HMAC,其中HMAC中的H就是Hash的意思。使用SHA-1、SHA-224、SHA-256、SHA-384、SHA-512所构造的HMAC,分别称为HMAC-SHA1、HMAC-SHA-224、HMAC-SHA-384、HMAC-SHA-512。

二、实现原理

实现原理图:
在这里插入图片描述

以摘要算法为MD5实现的HMAC为例(MD5将原文以64字节分组来进行分别计算,最终输出一个16字节的散列值),如上图所示,HMAC的计算公式为:
HMAC(K,M)=H(K⊕opad∣H(K⊕ipad∣M)),其中,
B为计算hash过程中对信息分组时,每个信息块的长度(MD5算法中B=64);
L为哈希算法计算出的信息摘要长度(MD5算法中L=16);
K为任意长度的密钥,一般为了安全强度考虑,K的长度不小于L;
Ipad为00110110(16进制为0x36)重复B次;
Opad为01011100(16进制为0x5c)重复B次;
M 代表一个消息输入,即待加密原文;
H为哈希函数(例如MD5)。
根据上面的算法表示公式,我们可以描述HMAC算法的运算步骤:
(1)检查密钥K的长度。如果K的长度大于B则先使用摘要算法计算出一个长度为L的新密钥。如果后K的长度小于B,则在其后面追加0来使其长度达到B。
(2)将上一步生成的B字长的密钥字符串与ipad做异或运算,得到比特序列ipadkey。
(3)将ipadkey附加在消息M的开头;
(4)使用哈希函数H计算第3步中生成的数据流的信息摘要值。
(5) 将第1步生成的B字长密钥字符串与opad做异或运算,得到opadkey。
(6)再将第4步得到的结果填充到opadkey之后。
(7)使用哈希函数H计算第6步中生成的数据流的信息摘要值,输出结果就是最终的HMAC值。

SM3-HMAC实现示例

public static byte[] SM3HashMac(String text,String key){
        //1.填充0至key,或者hashkey,使其长度为sm3分组长度
        /** BLOCK_LENGTHSM3分组长度 ,64个字节,512位*/
        byte[] sm3_key;
        byte[] structured_key=new byte[BLOCK_LENGTH];
        byte[] IPAD=new byte[BLOCK_LENGTH];
        byte[] OPAD=new byte[BLOCK_LENGTH];
        if(StringUtil.base64Decode(key).length>BLOCK_LENGTH){
            sm3_key= sm3Hash(StringUtil.base64Decode(key));
            System.arraycopy(sm3_key,0,structured_key,0,sm3_key.length);
        }else {
            System.arraycopy(StringUtil.base64Decode(key),0,structured_key,0,StringUtil.base64Decode(key).length);
        }
        //2.让处理之后的key 与ipad (分组长度的0x36)做异或运算
        for(int i=0;i<BLOCK_LENGTH;i++){
            IPAD[i]=0x36;
            OPAD[i]=0x5c;
        }
        byte[] ipadkey=XOR(structured_key,IPAD);
        //3.将2的结果与text拼接
        int textLen=text.getBytes().length;
        byte[] t3=new byte[BLOCK_LENGTH+textLen];
        System.arraycopy(ipadkey,0,t3,0,ipadkey.length);
        System.arraycopy(text.getBytes(),0,t3,ipadkey.length,text.getBytes().length);
        //4.将3的结果sm3 哈希
        byte[] t4=sm3Hash(t3);
        //5.让处理之后的key 与opad(分组长度的0x5c)做异或运算
        byte[] opadkey=XOR(structured_key,OPAD);
        //6.4的结果拼接在5之后
        byte[] t6=new byte[BLOCK_LENGTH+t4.length];
        System.arraycopy(opadkey,0,t6,0,opadkey.length);
        System.arraycopy(t4,0,t6,opadkey.length,t4.length);
        //7.对6做hash
        return (sm3Hash(t6));
    }

参考文档

https://www.cnblogs.com/foxclever/p/8593072.html
https://blog.csdn.net/chengqiuming/article/details/82822933

  • 9
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HMAC-SM3是一种基于SM3 Hash算法的消息认证码。实现HMAC-SM3需要以下步骤: 1. 准备输入数据和HMAC密钥。 2. 对密钥进行预处理,如果密钥长度超过64字节,直接对密钥进行SM3散列;如果密钥长度小于等于64字节,将其追加0x00字节填充至64字节并保存为MK,将0x5C字节追加至MK的每个字节的右侧,并保存为Ko。 3. 将0x36字节追加至MK的每个字节的右侧,并保存为Ki。 4. 将步骤2和步骤3得到的Ko和Ki分别作为秘钥,对输入数据进行SM3散列运算。得到两个SM3散列值H1和H2。 5. 将步骤4得到的H1和H2连接起来作为新的输入数据,再次进行SM3散列运算。得到最终的MAC值。 以下是HMAC-SM3代码实现的示例: ```python import hashlib def hmac_sm3(key, message): key = bytearray.fromhex(key) # 将密钥从十六进制字符串转换为字节数组 if len(key) > 64: key = hashlib.sm3(key).digest() # 如果密钥长度超过64字节,直接对密钥进行SM3散列 elif len(key) < 64: key += bytearray(64 - len(key)) # 如果密钥长度小于等于64字节,填充0x00字节至64字节 ko = bytearray(hex(0x5C ^ b)[2:].zfill(2) for b in key) # 生成Ko ki = bytearray(hex(0x36 ^ b)[2:].zfill(2) for b in key) # 生成Ki h1 = hashlib.sm3(bytes(ki + message)).digest() # 使用Ki对消息进行SM3散列 h2 = hashlib.sm3(bytes(ko + message)).digest() # 使用Ko对消息进行SM3散列 mac = hashlib.sm3(bytes(h1 + h2)).hexdigest() # 将H1和H2连接后再进行SM3散列,得到最终的MAC值 return mac key = "0123456789ABCDEF" # HMAC密钥,长度为16个字节 message = "Hello HMAC-SM3!" # 输入数据 mac = hmac_sm3(key, message) print(mac) ``` 此代码示例使用Python编程语言实现HMAC-SM3算法。注意,SM3算法实现需要依赖相应的密码学库或算法实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值