如何在 hmac 中为消息添加另一个参数?

How to add another parameter for message in hmac?

我想在python中写一个hmac(基于散列的消息认证码)。到目前为止,我设法编写了基本的 hmac,但我想在消息中添加另一个参数。例如,消息=(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, 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")

            # 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, encoding="ascii"), shake_256)
print(cl.digest())
print("=="*10)

index = "1"
print(cl.digest(mac + index))
print("=="*10)
print(cl.digest_hmac_list)