问题描述
我想用python编写hmac(基于哈希的消息身份验证代码)。到目前为止,我设法编写了基本的hmac,但是我想在消息中添加另一个参数。例如,message =(mac_address || index_value)。有人可以告诉我该怎么做吗?以及如何将输出保存到另一个列表(例如digest_hmac_list)中?
from hashlib import shake_256
from zlib import crc32,adler32
class HMAC:
def __init__(self,key,message,hash_h=shake_256):
""" key and message must be byte object """
self.i_key_pad = bytearray()
self.o_key_pad = bytearray()
self.key = key
self.message = message
self.blocksize = 64
self.hash_h = hash_h
self.init_flag = False
def init_pads(self):
""" creating inner padding and outer padding """
for i in range(self.blocksize):
self.i_key_pad.append(0x36 ^ self.key[i])
self.o_key_pad.append(0x5c ^ self.key[i])
def init_key(self):
""" key regeneration """
if len(self.key) > self.blocksize:
self.key = bytearray(shake_256(key).digest())
elif len(self.key) < self.blocksize:
i = len(self.key)
while i < self.blocksize:
self.key += b"\x00"
i += 1
def digest(self):
if self.hash_h == adler32 or self.hash_h == crc32:
return self.hash_h(bytes(self.o_key_pad)+str(self.hash_h(bytes(self.i_key_pad)+self.message)).encode())
""" returns a digest,byte object. """
""" check if init_flag is set """
if self.init_flag == False:
self.init_key()
self.init_pads()
""" hold init_flag for good. """
self.init_flag = True
return self.hash_h(bytes(self.o_key_pad)+self.hash_h(bytes(self.i_key_pad)+self.message).digest()).digest()
def hexdigest(self):
if self.hash_h == adler32 or self.hash_h == crc32:
return hex(self.hash_h(bytes(self.o_key_pad)+str(self.hash_h(bytes(self.i_key_pad)+self.message)).encode()))[2:]
""" returns a digest in hexadecimal. """
""" check if init_flag is set """
if self.init_flag == False:
""" init key and padding. """
self.init_key()
self.init_pads()
""" set init_flag for good. """
self.init_flag = True
解决方法
我修复了您的代码中的一些小问题,并进行了改进,因此您可以使用相同的密钥哈希2个不同的(mac ||索引)并将其保存在self.digest_all_list
中。我在代码中注释了所有这些内容。
from hashlib import shake_256
from zlib import crc32,adler32
class HMAC:
def __init__(self,key,message,hash_h=shake_256):
""" key and message must be byte object """
self.i_key_pad = bytearray()
self.o_key_pad = bytearray()
self.key = key
self.message = message
self.blocksize = 64
self.hash_h = hash_h
self.init_flag = False
# This will contain all hashed messages
self.digest_hmac_list = []
def init_pads(self):
""" creating inner padding and outer padding """
for i in range(self.blocksize):
self.i_key_pad.append(0x36 ^ self.key[i])
self.o_key_pad.append(0x5c ^ self.key[i])
def init_key(self):
""" key regeneration """
if len(self.key) > self.blocksize:
self.key = bytearray(shake_256(self.key).digest(self.blocksize))
elif len(self.key) < self.blocksize:
i = len(self.key)
while i < self.blocksize:
self.key += b"\x00"
i += 1
def digest(self,message = None):
# If you want to Hash 2 different message with same key(so same class instance)
# pass message to digest and default to self.message
if message:
self.message = bytearray(message,encoding="ascii")
if self.hash_h == adler32 or self.hash_h == crc32:
return self.hash_h(bytes(self.o_key_pad)+str(self.hash_h(bytes(self.i_key_pad)+self.message)).encode())
""" returns a digest,byte object. """
""" check if init_flag is set """
if self.init_flag == False:
self.init_key()
self.init_pads()
""" hold init_flag for good. """
self.init_flag = True
# You Forget to specify the size of the Hash shake_256 allow for arbitrary output(Not like SHA-2)
#,I chosen 64 byte you can you chose whatever you want
self.digest_hmac_list.append(self.hash_h(bytes(self.o_key_pad) + self.hash_h(bytes(self.i_key_pad) + self.message).digest(self.blocksize)).digest(self.blocksize))
return self.digest_hmac_list[-1]
def hexdigest(self,encoding="ascii")
# Checking must be Done First So you can initialize all required parts then hash the message
""" check if init_flag is set """
if self.init_flag == False:
""" init key and padding. """
self.init_key()
self.init_pads()
""" set init_flag for good. """
self.init_flag = True
if self.hash_h == adler32 or self.hash_h == crc32:
self.digest_hmac_list.append(hex(self.hash_h(bytes(self.o_key_pad) + str(self.hash_h(bytes(self.i_key_pad) + self.message)).encode())[2:]))
return self.digest_hmac_list[-1]
""" returns a digest in hexadecimal. """
# NOTE: You are Not hashing anything if the default Hash function is shake_256,add
# code here to add hexHashing for default
# message is mac then post pended with Index if that what I understand
index = "0"
mac = "FF0A8CD1DAAB"
key = "This is key"
cl = HMAC(bytearray(key,encoding="ascii"),bytearray(mac + index,shake_256)
print(cl.digest())
print("=="*10)
index = "1"
print(cl.digest(mac + index))
print("=="*10)
print(cl.digest_hmac_list)