【问题标题】:Mifare DESFIRE EV1 GetCardUidMifare 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;
    }

我查看了以下资源

...并尝试这样做:

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

【问题讨论】:

    标签: c# .net smartcard des mifare


    【解决方案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 状态字,意思是错误的长度)。

      【讨论】:

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