Mifare DESFIRE EV1 GetCardUid

Posted

技术标签:

【中文标题】Mifare DESFIRE EV1 GetCardUid【英文标题】: 【发布时间】:2013-02-21 11:57:12 【问题描述】:

下面的代码有效,并允许我获取 Mifare 1k 卡的 UID。不幸的是,它不适用于 Desfire 卡。

    public byte[] GetUid()
    
        byte[] uid = new byte[6];
        int rc = Communicate(new byte[]0xff, 0xca, 0x00, 0x00, 0x04, ref uid);
        if (rc != 0)
            throw new Exception("failure: " + rc);

        int rc1, rc2;
        if (uid.Length == 2)
        
            rc1 = uid[0];
            rc2 = uid[1];
        
        else
        
            rc1 = uid[4];
            rc2 = uid[5];
        

        if (rc1 != 0x90 || rc2 != 0x00)
            throw new Exception("failure: " + rc1 + "/" + rc2);

        byte[] result = new byte[4];
        Array.Copy(uid, result, 4);
        return result;
    

我查看了以下资源

http://ridrix.wordpress.com/2009/09/19/mifare-desfire-communication-example/ http://code.google.com/p/nfc-tools/source/browse/trunk/libfreefare/libfreefare/mifare_desfire.c?r=532

...并尝试这样做:

        byte[] outb = new byte[15];
        int rc9 = Communicate(new byte[]  0x60 , ref outb);

outb 始终包含 0x67, 0x00 ,而不是预期的 af 04 01 01 00 02 18 05 。

连接成功,SCardGetAttrib 允许我获取 ATR。 Communicate 方法适用于 SCardTransmit。如果有帮助,我可以发布代码。

感谢您的指点!

编辑

感谢您的第一个回答!我按照建议更改了程序:

        byte[] outb = new byte[9];
        int rc5 = Communicate(new byte[]0x90, 0x60, 0x00, 0x00, 0x00, 0x00, ref outb);

现在 outb 是 0x91, 0x7E 。这似乎更好,0x91 看起来像 ISO 7816 响应代码,但不幸的是不是 0x90,正如预期的那样。 (我还查看了第二个链接中的 DESFIRE_TRANSCEIVE 宏,如果它收到 0xf2 则继续读取。)我尝试在 Google 上搜索 ISO 7816 APDU 响应代码,但未能成功解码错误代码。

编辑 2

我还发现了以下评论:

使用全键 5321 我得到 DESFire ATR 3B8180018080 UID 04 52 2E AA 47 23 80 90 00 [来自 apdu FFCA000000] 所有其他 apdu 给 917E 未知 错误

这解释了我的错误代码并给了我另一个提示,FFCA000000 看起来与我的其他 Mifare 1k 字符串非常相似。因此,使用 FFCA000000 我会得到一个似乎包含 UID 的 9 字节响应。有趣的是,FFCA000000 代码也适用于 1k 卡,所以也许我的解决方案只是将最后的 04 更改为 00 并处理不同长度的响应。对吧?

编辑 3

似乎一分钱掉了... 0x04 = 4 字节响应 = 对于 7 字节 UID 来说太小 = 响应 917E = 缓冲区太小 :-)

【问题讨论】:

【参考方案1】:

此代码似乎有效:

        int rc = Communicate(new byte[]  0xff, 0xca, 0x00, 0x00, 0x00 , ref uid);
        if (rc != 0)
            throw new Exception("failure: " + rc);

        int rc1 = uid[uid.Length-2], rc2 = uid[uid.Length-1];

        if (rc1 != 0x90 || rc2 != 0x00)
            throw new Exception("failure: " + rc1 + "/" + rc2);

        byte[] result = new byte[uid.Length - 2];
        Array.Copy(uid, result, uid.Length - 2);
        return result;

有没有cmets?

【讨论】:

感谢您与我们分享代码,很高兴我在正确的方向上帮助了您。 这是在哪个硬件上测试的? Mifare DESfire EV1、Mifare Classic 1k 和 Mifare Classic 4k。【参考方案2】:

Cla=ff 命令是 pcsc 第 3 部分命令。 Ins=ca 应该适用于任何符合 pcsc 2.0x 的 cl 阅读器

【讨论】:

【参考方案3】:

尝试使用您提供的第一个链接的“原生包装”版本。您的界面需要 ISO 7816-4 样式的 APDU(因为它返回一个 ISO 7816-4 状态字,意思是错误的长度)。

【讨论】:

以上是关于Mifare DESFIRE EV1 GetCardUid的主要内容,如果未能解决你的问题,请参考以下文章

使用 javax.smartcardio 时 DESfire EV1 为 PPS 命令包装 APDU 的问题

从 MIFARE DESFire 获取 UID 的 APDU?

Mifare DESFire 读取文件

Mifare desfire apdu 命令

Mifare卡版获取方法

黑莓 10 NFC 支持