使用Desfire本机包装的APDU与卡进行通信时,必须使用命令和响应的哪一部分来计算CMAC?
成功认证后,我具有以下 session 密钥:
Session Key: 7CCEBF73356F21C9191E87472F9D0EA2
然后,当我发送GetKeyVersion命令时,卡将返回以下我要验证的CMAC:
<< 90 64 00 00 01 00 00
>> 00 3376289145DA8C27 9100
我已经根据“NIST特殊出版物800-38B”实施了CMAC算法,并确保它是正确的。但是我不知道必须使用命令和响应APDU的哪些部分来计算CMAC。
我正在使用TDES,所以MAC为8字节。
最佳答案
最近几天,我一直在研究完全相同的问题,我想至少可以为您提供一些建议。使一切“如此”花费了一些时间,并且在某些情况下,很难理解NXP的文档(假设您可以访问)。
因此,您可能知道,您需要在发送和接收时计算CMAC(并更新init vec)。每次将其计算为下一个加密操作的初始化vec(CMAC或加密等)时,都需要保存CMAC。
计算示例的CMAC时,要馈入CMAC算法的数据是INS字节(0x64
)和命令数据(0x00
)。当然,这将由CMAC指定进行填充等。但是请注意,您不会在整个APDU包装(即90 64 00 00 01 00 00
)中计算CMAC,而仅使用INS字节和数据有效负载。
接收时,您需要获取数据(0x00
)和第二个状态字节(也为0x00
),并根据该值计算CMAC。在此示例中这并不重要,但是顺序在这里很重要。您使用响应正文(不包括CMAC),然后使用SW2。
请注意,实际上仅发送了一半的CMAC-CMAC应该产生16个字节,而卡正在发送前8个字节。
还有其他一些因素阻止了我:
我仍在正确计算“写入数据”命令的响应。命令成功,但是我无法验证CMAC。我确实知道写入数据不是用CMAC填充填充的,而只是用零填充的-尚不确定我还错过了什么。
最后,这是一个通过我的日志与卡片进行通信的真实示例:
F92E48F9A6C34722A90EA29CFA0C3D12
;初始vec为零6400
计算CMAC并获取1200551CA7E2F49514A1324B7E3428F1
(现在是我的下一次计算的初始化vec)90640000010000
发送到卡并接收00C929939C467434A8
(状态为9100)。 00 00
计算CMAC并获取C929939C467434A8A29AB2C40B977B83
(并更新init vec以进行下一次计算)