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

2024-05-16 16:33:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用python编写一个hmac(基于哈希的消息身份验证代码)。到目前为止,我成功地编写了基本的hmac,但我想在消息中添加另一个参数。例如,message=(mac|U地址|索引|U值)。有人能告诉我怎么做吗?如何将输出保存在另一个列表中(例如digest\u hmac\u列表)

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

Tags: keyselfmessageifbytesinitdefhash
1条回答
网友
1楼 · 发布于 2024-05-16 16:33:37

我修复了代码中的一些小问题,并将其制作成可以用同一个键散列2个不同的(mac | | index)并将其保存在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)

相关问题 更多 >