这个 CMAC 计算有什么问题?
What is wrong with this CMAC computation?
我有一个 CMAC 计算示例,我想在 Python 中复制它,但我失败了。该示例如下所示:
key = 3ED0920E5E6A0320D823D5987FEAFBB1
msg = CEE9A53E3E463EF1F459635736738962&cmac=
预期的(截断的)CMAC 看起来像这样(注意:截断意味着每隔一个字节被丢弃)
ECC1E7F6C6C73BF6
所以我尝试用下面的代码重现这个例子:
from Crypto.Hash import CMAC
from Crypto.Cipher import AES
from binascii import hexlify, unhexlify
def generate_cmac(key, msg):
"""generate a truncated cmac message.
Inputs:
key: 1-dimensional bytearray of arbitrary length
msg: 1-dimensional bytearray of arbitrary length
Outputs:
CMAC: The cmac number
CMAC_t: Trunacted CMAC"""
# Generate CMAC via the CMAC algorithm
cobj = CMAC.new(key=key, ciphermod=AES)
cobj.update(msg)
mac_raw = cobj.digest()
# Truncate by initializing an empty array and assigning every second byte
mac_truncated = bytearray(8 * b'\x00')
it2 = 0
for it in range(len(mac_raw)):
if it % 2:
mac_truncated[it2:it2+1] = mac_raw[it:it+1]
it2 += 1
return mac_raw, mac_truncated
key = unhexlify('3ED0920E5E6A0320D823D5987FEAFBB1') # The key as in the example
msg = 'CEE9A53E3E463EF1F459635736738962&cmac=' # The msg as in the example
msg_utf = msg.encode('utf-8')
msg_input = hexlify(msg_utf) # Trying to get the bytearray
mac, mact_calc = generate_cmac(key, msg_input) # Calculate the CMAC and truncated CMAC
# However the calculated CMAC does not match the cmac of the example
我的函数 generate_cmac()
适用于其他情况,为什么不适用于此示例?
(如果有人好奇的话,这个例子源于this document第18页/Table6)
编辑:成功的 cmac 计算示例如下:
mact_expected = unhexlify('94EED9EE65337086') # as stated in the application note
key = unhexlify('3FB5F6E3A807A03D5E3570ACE393776F') # called K_SesSDMFileReadMAC
msg = [] # zero length input
mac, mact_calc = generate_cmac(key, msg) # mact_expected and mact_calc are the same
assert mact_expected == mact_calc, "Example 1 failed" # This assertion passes
TLDR:过度化
令我震惊的是,linked example 确实似乎意味着 CEE9A53E3E463EF1F459635736738962&cmac=
当它写道时,因为下面的框包含 76 个十六进制字符,用于 ASCII 中的 38 字节编码,即434545394135334533453436334546314634353936333537333637333839363226636d61633d
.
不过,我确信这不需要像代码那样在 76 字节的曲调上进一步十六进制化。换句话说,我的赌注是
key = unhexlify('3ED0920E5E6A0320D823D5987FEAFBB1')
msg = 'CEE9A53E3E463EF1F459635736738962&cmac='.encode()
mac, mact_calc = generate_cmac(key, msg)
我有一个 CMAC 计算示例,我想在 Python 中复制它,但我失败了。该示例如下所示:
key = 3ED0920E5E6A0320D823D5987FEAFBB1
msg = CEE9A53E3E463EF1F459635736738962&cmac=
预期的(截断的)CMAC 看起来像这样(注意:截断意味着每隔一个字节被丢弃)
ECC1E7F6C6C73BF6
所以我尝试用下面的代码重现这个例子:
from Crypto.Hash import CMAC
from Crypto.Cipher import AES
from binascii import hexlify, unhexlify
def generate_cmac(key, msg):
"""generate a truncated cmac message.
Inputs:
key: 1-dimensional bytearray of arbitrary length
msg: 1-dimensional bytearray of arbitrary length
Outputs:
CMAC: The cmac number
CMAC_t: Trunacted CMAC"""
# Generate CMAC via the CMAC algorithm
cobj = CMAC.new(key=key, ciphermod=AES)
cobj.update(msg)
mac_raw = cobj.digest()
# Truncate by initializing an empty array and assigning every second byte
mac_truncated = bytearray(8 * b'\x00')
it2 = 0
for it in range(len(mac_raw)):
if it % 2:
mac_truncated[it2:it2+1] = mac_raw[it:it+1]
it2 += 1
return mac_raw, mac_truncated
key = unhexlify('3ED0920E5E6A0320D823D5987FEAFBB1') # The key as in the example
msg = 'CEE9A53E3E463EF1F459635736738962&cmac=' # The msg as in the example
msg_utf = msg.encode('utf-8')
msg_input = hexlify(msg_utf) # Trying to get the bytearray
mac, mact_calc = generate_cmac(key, msg_input) # Calculate the CMAC and truncated CMAC
# However the calculated CMAC does not match the cmac of the example
我的函数 generate_cmac()
适用于其他情况,为什么不适用于此示例?
(如果有人好奇的话,这个例子源于this document第18页/Table6)
编辑:成功的 cmac 计算示例如下:
mact_expected = unhexlify('94EED9EE65337086') # as stated in the application note
key = unhexlify('3FB5F6E3A807A03D5E3570ACE393776F') # called K_SesSDMFileReadMAC
msg = [] # zero length input
mac, mact_calc = generate_cmac(key, msg) # mact_expected and mact_calc are the same
assert mact_expected == mact_calc, "Example 1 failed" # This assertion passes
TLDR:过度化
令我震惊的是,linked example 确实似乎意味着 CEE9A53E3E463EF1F459635736738962&cmac=
当它写道时,因为下面的框包含 76 个十六进制字符,用于 ASCII 中的 38 字节编码,即434545394135334533453436334546314634353936333537333637333839363226636d61633d
.
不过,我确信这不需要像代码那样在 76 字节的曲调上进一步十六进制化。换句话说,我的赌注是
key = unhexlify('3ED0920E5E6A0320D823D5987FEAFBB1')
msg = 'CEE9A53E3E463EF1F459635736738962&cmac='.encode()
mac, mact_calc = generate_cmac(key, msg)