Mifare Desfire的MAC和CMAC计算

3

有没有人能帮我指导如何计算Mifare Desfire的MAC(4字节)和CMAC(8字节)?我得到了意外的结果。

Deskey      =   0000000000000000
Block1(B1)  =   1122334455667788
Block2(B2)  =   9900112200000000
IV          =   0000000000000000
sessionkey  =   2923be84b1495461


R1 = Enc(B1 xor IV)         f2f13994d24714ca
R2 = Enc(R1 xor B2)         880fe38ab9e8a8d3
MAC   880fe38a

Expected MAC =  c8d70ad2 95a88a36

CMAC结果

AESKey          =       00000000000000000000000000000000
Block           =       000102030405060708090a0b0c0d0e0f
Enc(Block)      =       7aca0fd9bcd6ec7c9f97466616e6a282
SubKey1         =       CDD297A9DF1458771099F4B39468565C
SubKey2         =       9BA52F53BE28B0EE2133E96728D0AC3F
CMAC(16bytes)   =       8A57896F795CB6ABF6867DAD41A5FB15

CMAC 只由 DES 和 TDES 生成,这是否属实?就像在零售 MAC 计算中,DES 加密所有块,除了最后一个块应该使用 TDES 加密一样。


1
我非常确定你不应该分发那份文档,Studuino。 - Maarten Bodewes
嗨,owlstead,我从互联网上得到了这个..它与菲利普斯的NDA有关吗? - Studuino
我无法在谷歌上找到那份文件,而且它被剥去了NXP标志,这表明它是真的。 - Maarten Bodewes
你使用了什么来生成上面的输出?你有代码分享吗?用的是哪种语言? - Duncan Jones
1
附注:0x0000000000000000 不是有效的DES密钥。 DES密钥需要为每个字节设置奇偶校验位。 0x0101010101010101 将是有效的。 - Duncan Jones
显示剩余2条评论
1个回答

2

就MAC计算而言,它似乎是数据的3DES CBC模式加密,明文上进行零填充,并且使用全零IV。 3DES密钥是通过将会话密钥异或24个零字节来创建的。这里是Java中的一个例子:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.xml.bind.DatatypeConverter;

public class MACTest {

  public static void main(String[] args) throws Exception {

    final byte[] keyBytes = new byte[24];
    final byte[] paddedPlaintext = 
        hexStringToByteArray("11223344556677889900112200000000");
    final byte[] iv = new byte[8];
    final byte[] sessionKeyBytes = hexStringToByteArray("2923be84b1495461");

    final byte[] derivedKeyBytes = new byte[24];
    for (int i = 0; i < sessionKeyBytes.length; i++) {
      derivedKeyBytes[i] = (byte) (keyBytes[i] ^ sessionKeyBytes[i]);
    }

    System.out.println(toHexString(derivedKeyBytes));
    SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
    SecretKey derivedKey = factory.generateSecret(new DESedeKeySpec(
        derivedKeyBytes));

    Cipher c = Cipher.getInstance("DESede/CBC/NoPadding");
    c.init(Cipher.ENCRYPT_MODE, derivedKey, new IvParameterSpec(iv));
    byte[] result = c.doFinal(paddedPlaintext);
    System.out.println(toHexString(result));
  }

  public static String toHexString(byte[] array) {
    return DatatypeConverter.printHexBinary(array);
  }

  public static byte[] hexStringToByteArray(String s) {
    return DatatypeConverter.parseHexBinary(s);
  }
}

输出:

2923BE84B149546100000000000000000000000000000000
F2F13994D24714CA880FE38AB9E8A8D3

您没有提供足够的信息来理解计算AES CMAC示例所需的内容,也不清楚您的问题实际是什么。可能您没有得到预期的结果?


嗨 Duncan,感谢您演示MAC计算。我得到了与我的问题中相同的输出。但正确的MAC是C8D70AD2 95A88A36。实际上是前四个字节(C8D70AD2)。我还根据ISO 9797进行了尝试http://en.wikipedia.org/wiki/ISO/IEC_9797-1,但这些算法也没有给出我需要的输出。我不知道我错在哪里。由于会话密钥仅为8个字节长(但我也尝试过这种加密),所以我无法使用TDES加密。 - Studuino
@Studuino 我本来以为你最初提供的链接中包含了与我的答案相同的MAC地址。你确定正确答案是什么吗?也许你可以发布文档中显示的示例值(我记得与你的问题略有不同)。 - Duncan Jones
示例中的输入为DES密钥0000000000000000。明文消息是112233445566778899001122,因此带有填充的消息是11223344556677889900112200000000。会话密钥为2923be84b1495461,示例输出为f2f13994d24714cac8d70ad295a88a36,因此数据+ MAC(4字节)为112233445566778899001122c8d70ad2。敬礼 - Studuino
@Studuino 啊,我的错误。我没有注意到我的输出的第二个块是不正确的。我会调查一下。 - Duncan Jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接