我正在尝试从 ISO/IEC 14443 Type A 卡中读取一些信息。
在使用android应用程序 NFC TagInfo 分析卡后,我发现该应用程序(AID:15845F)具有所需的特定文件(文件ID:01)。
我已经设法连接到卡并选择了应用程序。
String action = getIntent().getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action))
{
Tag tagFromIntent = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
Log.i(TAG, Arrays.toString(tagFromIntent.getTechList()));
IsoDep isoDep = IsoDep.get(tagFromIntent);
try
{
isoDep.connect();
byte[] SELECT = {
(byte) 0x00, // CLA = 00 (first interindustry command set)
(byte) 0xA4, // INS = A4 (SELECT)
(byte) 0x04, // P1 = 04 (select file by DF name)
(byte) 0x0C, // P2 = 0C (first or only file; no FCI)
(byte) 0x06, // Lc = 6 (data/AID has 6 bytes)
(byte) 0x31, (byte) 0x35,(byte) 0x38,(byte) 0x34,(byte) 0x35,(byte) 0x46 // AID = 15845F
};
byte[] result = isoDep.transceive(SELECT);
Log.i(TAG, "SELECT: " + bin2hex(result));
if (!(result[0] == (byte) 0x90 && result[1] == (byte) 0x00))
throw new IOException("could not select application");
byte[] GET_STRING = {
(byte) 0x00, // CLA Class
(byte) 0xB0, // INS Instruction
(byte) 0x00, // P1 Parameter 1
(byte) 0x00, // P2 Parameter 2
(byte) 0x04 // LE maximal number of bytes expected in result
};
result = isoDep.transceive(GET_STRING);
Log.i(TAG, "GET_STRING: " + bin2hex(result));
}
}
但是我的第二次查询失败,并显示错误代码:6A86(参数P1-P2不正确)。我已经在Google上搜索了很多,找到了不同的文档(例如:http://bit.ly/180b6tB),但是我不明白如何为 P1 和 P2 实现正确的值。
编辑
使用 NFC TagInfo 的卡的标签类型:ISO/IEC 14443-4智能卡,Mifare DESFire EV1(MF3ICD81)
源代码中使用的SELECT命令实际上没有失败,而是返回了9000响应。因此,这就是为什么我认为一切正常的原因。
您提到 NFC TagInfo 没有为DF名称等提供正确的值。值 0x313538343546 是否正确,您如何找到它?
您能给我一个简短的描述,我如何获得我想要的数据?还有其他我可以用来读取正确的DF名称,AID等的android应用吗?我基本上需要从一个应用程序中获取一个文件。如果需要,我还可以提供一些使用 NFC TagInfo 收集的信息的屏幕截图。
编辑2
我已经重写了命令,但是(按照您的建议)将它们保留在APDU包装器中。因此,我最终得到了两个不同的命令,一个用于选择应用程序,另一个用于选择文件。
private final byte[] NATIVE_SELECT_APP_COMMAND = new byte[]
{
(byte) 0x90, (byte) 0x5A, (byte) 0x00, (byte) 0x00, 3, // SELECT
(byte) 0x5F, (byte) 0x84, (byte) 0x15, (byte) 0x00 // APPLICATION ID
};
private final byte[] NATIVE_SELECT_FILE_COMMAND = new byte[]
{
(byte) 0x90, (byte) 0xBD, (byte) 0x00, (byte) 0x00, 7, // READ
(byte) 0x01, // FILE ID
(byte) 0x00, (byte) 0x00, (byte) 0x00, // OFFSET
(byte) 0x00, (byte) 0x00, (byte) 0x00, // LENGTH
(byte) 0x00
};
搜索 native Mifire-Desfire命令的教程失败,因此,我坚持以下教程:http://noobstah.blogspot.de/2013/04/mifare-desfire-ev1-and-android.html
本教程提供了卡身份验证功能,该功能已被我禁用,并且还使用了收发方法,据我所知,这不是执行 native 命令的正确方法吗?哪种方法(甚至可能是代码 fragment )用于执行 native 命令?我应该使用哪个Android级?
我已经重写了教程中提供的类,并将其上载到pastebin。执行完类后,我得到了以下结果。
Select APPLICATION: 9100
Read DATA: 91AE
在这一点上,我很困,不知道下一步该怎么做。究竟是错误,还是应该对查询执行哪些更改以获取所需的数据?
最佳答案
给定您从NFC TagInfo中提取的信息以及要尝试使用的命令,我假设该卡为MIFARE DESFire EV1。正确的?
关于您的选择命令:NFC TagInfo当前不读取DESFire EV1的ISO命令集中使用的DF名称值。因此,我假设为此应用程序设置的DF名称实际上是0x313538343546,否则SELECT命令应该失败。但是请注意,该值绝不能从NFC TagInfo中显示的DESFire AID派生!实际上,DF名称是在应用程序创建期间定义的单独值。 (这与以前的DESFire版本不同。)
关于您的READ BINARY命令:您使用的命令暗示您以前选择了一个文件。但是,您仅选择了该应用程序。因此,您将需要为数据文件发出SELECT命令,或者在READ BINARY命令中使用短文件ID:
byte[] READ_BINARY = {
(byte) 0x00, // CLA Class
(byte) 0xB0, // INS Instruction
(byte) 0x80, // P1 (indicate use of SFI)
(byte) 0x01, // P2 (SFI = 0x01)
(byte) 0x04 // LE maximal number of bytes expected in result
};
但是,当涉及到DESFire(EV1)时,我建议您宁愿使用DESFire native 命令集(直接或包装),而不要使用ISO 7816-4 APDU。
通过 native 命令集,您可以获得MIFARE DESFire的全部功能。通过将 native DESFire命令嵌入ISO 7816-4 APDU结构中来完成命令包装。包装命令如下所示:
0x90 CMD 0x00 0x00 LEN CMD-PARAM 0x00
其中CMD是 native DESFire命令,而CMD-PARAM是命令参数。响应为:
[DATA] 0x91 STATUS
其中status是 native DESFire状态代码。如果STATUS为0xAF,则可以通过发出以下命令来获取剩余的响应数据:
0x90 0xAF 0x00 0x00 0x00
因此,在您的情况下,您将为应用程序0x15845F发出一个选择应用程序命令(请注意不同的字节顺序!):
0x90 0x5A 0x00 0x00 3 0x5F 0x84 0x15 0x00
|SELECT| |APPLICATION ID|
然后,您要读取数据文件0x01(整个文件,从偏移量0开始):
0x90 0xBD 0x00 0x00 7 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|READ| |FILE| OFFSET | LENGTH |
关于如何为应用程序获取ISO DF名称和ISO FID的问题,可以尝试以下命令:
选择主应用程序:
905A00000300000000
获取包含其DF名称的应用程序:
906D000000
选择您的应用程序:
905A0000035F841500
获取DESFire FID:
906F000000
获取ISO FID:
9061000000
您始终可以使用IsoDep对象的transceive()方法。无论如何都使用IsoDep(即ISO/IEC 14443-4)(用于 native DESFire命令,包装的 native 命令和ISO 7816-4命令)。
您从卡收到的错误代码(0xAE)表示身份验证错误(有关更多信息,请参见此数据表:DESFire)。因此,该文件允许经过身份验证的只读文件(请参阅NFC TagInfo中显示的访问条件)。
因此,为了读取此文件,您将需要实现身份验证过程。