以下代码有效并允许我获取 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:
我还发现了以下评论:
使用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 = 缓冲区太小 :-)