2013-10-10 143 views
6

我想看过一些资料出ISO/IEC 14443 A类卡。Android的NFC读取IsoDep文件内容

使用android应用程序分析卡片后,我发现应用程序(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),但我只是不明白,我怎么能实现正确的值为P1P2


EDIT

标签使用NFC TagInfo卡的类型:ISO/IEC 14443-4智能卡,的Mifare的DESFire EV1(MF3ICD81)

SELECT命令中使用的源代码实际上没有失败,但是它返回了一个9000响应。所以这就是为什么我认为一切正常。

你提到NFC TagInfo没有为DF-名称等提供正确值是值0x313538343546正确的,你是怎么发现的?

你能提供给我一个描述,我怎么能得到我想要的数据?有没有其他的Android应用可以用来阅读正确的DF名称,AID等?基本上,我需要得到ONE文件出来ONE应用。如果需要,我还可以提供与NFC TagInfo收集的信息的一些屏幕截图。


EDIT 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 
}; 

为本地Mifire-DESFIRE命令教程搜索没有成功,所以我坚持到下面的教程:http://noobstah.blogspot.de/2013/04/mifare-desfire-ev1-and-android.html

本教程提供了一个卡认证,这是我残疾,并且还使用了收发方法,这对我的理解是不是执行本机命令的正确方法?哪种方法,甚至是代码snippit,用于执行本机命令?我应该使用哪个Android类?

我已经重写了教程中提供的类,并将其上载到pastebin。执行这个类后,我得到了以下结果。

Select APPLICATION: 9100 
Read DATA: 91AE 

在这一点上我很卡,不知道我下一步应该怎么做几步之遥。实际上是错误还是我应该执行的查询中的更改以获取我想要的数据?

回答

8

鉴于您从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本机命令集(直接或包装)而不是使用ISO 7816-4 APDU。

使用本机命令集,您将获得MIFARE DESFire的全部功能。命令包装是通过将本地DESFire命令嵌入到ISO 7816-4 APDU结构中完成的。包装命令如下所示:

0x90 CMD 0x00 0x00 LEN CMD-PARAM 0x00 

其中,CMD是本机DESFire命令,CMD-PARAM是命令参数。答案是:

[DATA] 0x91 STATUS 

其中status是本地DESFire状态码。如果状态是0xAF执行,您可以通过发出以下命令获得剩余的响应数据:

0x90 0xAF 0x00 0x00 0x00 

所以你的情况,你会为你的应用0x15845F发出选择应用命令(介意不同的字节顺序!):

0x90 0x5A 0x00 0x00 3 0x5F 0x84 0x15 0x00 
    |SELECT|   |APPLICATION ID| 

然后,你要读取数据文件0×01(整个文件,开始在偏移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对象的transceiver()方法。无论如何都使用IsoDep(即ISO/IEC 14443-4)(用于本地DESFire命令,用于包装原生命令和用于ISO 7816-4命令)。

您从卡(0xAE)收到的错误代码表示验证错误(有关更多信息,请参阅此数据表:DESFire)。因此,该文件允许认证只读(请参阅NFC TagInfo中显示的访问条件)。

因此,为了读取此文件,您将需要实现身份验证过程。

+0

感谢您的快速响应!我刚刚编辑了我的文章,并在其底部提供了其他信息。 – Vilius

+0

感谢您的帮助,但我仍然陷入困境,我刚刚编辑了我的文章并提供了更多信息。 – Vilius

+0

我已经更新了答案。不幸的是,我无法帮助您实施身份验证程序。 –