基于Python的SM3 Hash及Hmac

Hash及Hmac

Hash算法,主要用于获取摘要值,由于其不可逆向,从而保证明文的完整性。
Hmac在Hash的基础上引入了密钥,在Hmac的计算过程中通过两次异或,两次Hash得出消息认证码。目前SSL协议、IPsec协议、SSH协议等在通信过程中都使用了Hmac算法保护数据的完整性。
Hmac比Hash多了一层安全性,使用Hash算法时如明文与摘要同时被篡改,则无法确保其完整性。使用Hmac算法时,在无法获取密钥的情况下即使篡改了明文与摘要,接收方也能通过Hmac算法判断其完整性遭到了破坏。

Hash实现

1.填充

Hash算法对数据输入长度无要求,因为在接受到原始输入后,必须对其进行填充使其长度为L的倍数,在SM3算法中,L为64(Byte)。
SM3算法的填充方式为:
首先将明文按照512bit分组,下文中提到的64bit的L为分组前整体数据的长度。
长度小于448bit时。
在明文后填充一个“1”,在尾部填充明文的长度L(L填充在最尾部,如L小于64bit,在高位填充0),然后在填充的“1”和尾部64bit的L之间填充0,使数据整体长度达到512bit。

输入数据(16进制)“616263>>>"61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018"

长度大于或等于448bit,但小于512bit时
在明文后填充一个“1”,然后在尾部填充0,使长度达到512bit。然后填充一组512bit数据(448个0+64bit的L)

输入数据(16进制)“616263800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000>>>6162638000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200

长度大于512bit时,判断最后一组数据的长度,然后按照上面的方式进行填充

输入数据(16进制)“616263800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”
分组后的数据:
>>>['61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018', '61']
填充后的数据:
>>>['61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018', '61800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000208']

长度等于512bit或为512bit的倍数时
在尾部填充一个“1”,447个“0”,以及64bit的L。

输入数据(16进制)“6162638000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001861626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018”
分组后的数据:
>>>['61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018', '61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018']
填充后的数据:
>>>['61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018', '61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018', '80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400']

代码实现

def group(list, n):##分组
    for i in range(0, len(list), n):
        yield list[i:i + n]
def sm3(data):
    l = len(data)//2
    byte = '{0:x}'.format(int(l*8))
    data_list = []
    [data_list.append(i) for i in group(data, 128)]
    m = l%64
    if m < 56 and m != 0:
        data_list[-1] = (data_list[-1]+'80').ljust(112,'0')+str(byte).rjust(16,'0')
    elif m >= 56:
        data_list[-1] = (data_list[-1]+'80').ljust(128,'0') 
        data_list.append(112*'0'+str(byte).rjust(16,'0'))
    elif m == 0:
        data_list.append('80'+110*'0'+str(byte).rjust(16,'0'))
    return data_list

2.迭代压缩

迭代压缩过程中主要使用异或、或、与、非运算以及32位循环左移,这里不再描述具体运算规则。
在迭代压缩过程中,为了方便,所有值都改为了10进制。
IV和TJ为GB-T32905给出的初始值与常量。

def xor(a,b):
    a1 = int(a,16)
    b1 = int(b,16)
    A = '{:08x}'.format(int(a1^b1))
    return A
def left_hex(list,n):
    out1 = '{:032b}'.format(int(list,16))
    out2 = out1[n:] + out1[:n]
    out_list = '{:08x}'.format(int(out2,2))
    return out_list
def left_int(list,n):
    out1 = '{:032b}'.format(list)
    out2 = out1[n:] +
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值