Mifare DESFIRE EV1 GetCardUid

时间:2013-02-21 11:57:13

标签: c# .net smartcard des mifare

以下代码有效并允许我获取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;
    }

我查看了以下资源

......并尝试这样做:

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

outb总是包含{0x67,0x00}而不是正如预期的那样{af 04 01 01 00 02 18 05}。

Connect是成功的,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,它继续读取。)我尝试了谷歌搜索ISO 7816 APDU响应代码,但没有成功解码错误代码。

编辑2

我还发现了以下评论:

  

使用omnikey 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 =缓冲区太小: - )

3 个答案:

答案 0 :(得分:3)

此代码似乎有效:

        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;

有任何意见吗?

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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