【问题标题】:How to calculate C-MAC from EXTERNAL AUTHENTICATE command apdu?如何从 EXTERNAL AUTHENTICATE 命令 apdu 计算 C-MAC?
【发布时间】:2020-12-08 20:03:51
【问题描述】:

谢谢to these informations 我可以计算EXTERNAL_AUTHENTICATE_data 但是我该如何计算MAC?

我知道我的默认 C-MAC 密钥是 [40 41 ... 4F]。我尝试在 CBC 模式下使用 3DES 加密 [84 82 00 00 10]+EXTERNAL_AUTHENTIFICATE apdu,但它没有给出我期望的 MAC 值。


this tutorial 的帮助下,这些是我“计算 C-MAC”所遵循的步骤:

1 - 我使用带有 EXTERNAL_AUTHENTICATE_data 的 apdu:8482000010448126B770B27702

2 - 我填充了这个 apdu:8482000010448126B770B27702800000

3 - 我使用 S-MAC 密钥的前 8 个字节 加密数据:CBC 模式下的单个 DES(密钥:D1C28C601652A477 / IV:00 00 00 00 00 00 00 00)结果 = > 25F7DC3B1FEE1B9018CCD8E66A69B560

4 - 我使用 S-MAC 密钥的最后 8 个字节 对其进行加密:EBC 模式下的 3DES(密钥:0D67AD82D2D2E1C4)结果 => 11E1B058F0EB6910196A68BF1FBA97AA

或者我除外的结果是D770D0A0001B05AA

我做错零售 MAC 了吗?

【问题讨论】:

    标签: security cryptography scp javacard apdu


    【解决方案1】:

    我为 SCP02 开发了一个 Python 类。 MAC相关部分可能会回答您的问题:

    from Crypto.Cipher import DES3,DES
    
    ZERO_IV_8 = b"\x00\x00\x00\x00\x00\x00\x00\x00"
    last_mac = None
    
    
    def pad_80(data_list):
        reminder = len(data_list) % 8 
        if reminder != 0:
            return data_list + [0x80,] + [0x00 for i in range(8 - reminder - 1)] 
        else:
            return data_list + [0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
    
    
    def calc_mac(command):
        padded_command = self.pad_80(command)
        mac_in = bytes.fromhex(toHexString(padded_command).replace(" ", ""))
    
        iv = ZERO_IV_8
        if last_mac != None:
            cipher = DES.new(session_mac[:8], DES3.MODE_ECB)
            iv = cipher.encrypt(last_mac)
    
        cipher = DES.new(session_mac[:8], DES3.MODE_CBC, iv) 
        step1 = cipher.encrypt(mac_in)
    
        cipher = DES.new(session_mac[8:16], DES3.MODE_ECB)
        step2 = cipher.decrypt(step1[-8:])
    
        cipher = DES.new(session_mac[:8], DES3.MODE_ECB)
        mac = list(bytes(cipher.encrypt(step2[-8:])))
    
        last_mac = bytes.fromhex(toHexString(mac).replace(" ", ""))
    
        return mac
    

    变量session_mac 是一个包含会话MAC 密钥的16 字节字节字符串。您还需要将计算出的 MAC 保存在一个变量中(在我的情况下为 last_mac),以将其用作下一个命令 MAC 计算的 IV。

    calc_mac 函数输入(命令)是作为 APDU 命令的数字列表。您需要在 MAC 计算之前修复 CLA 和 LC 值。

    【讨论】:

      【解决方案2】:

      我看到两个错误:

      1. 最后一个块需要加密 3 次而不是 4 次(单个 DES + 3DES 第一轮太多);
      2. 您没有为 3DES 使用两个密钥,在这种情况下,它可能会恢复为单一 DES 加密。

      至于最后一点,它使用给定的单个密钥执行 DES 加密,使用给定的单个密钥进行解密,然后再次进行最终加密。因此,其中两个操作相互抵消。这是在设计三重 3DES 时有意为之,以使单个硬件实现能够同时完成这两项工作。

      我认为在前面的问题中提到了这一点,但请注意,MAC 通常使用位填充:始终填充 0x80 的字节,并使用尽可能多的 0x00 字节到达下一个块边界。

      注意充气城堡contains Retail MAC

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多