HMAC原理及SM3-HMAC实现

HMAC原理及SM3-HMAC实现,第1张

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

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/993939.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存