以下代码有效并允许我获取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 =缓冲区太小: - )
答案 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状态字,意味着错误的长度)。