Android NFC读取标签类型:IsoDep和NfcB

7

我对Android开发和NFC技术都很陌生。

我正在尝试构建一个应用程序,以读取我不知道任何信息的NFC卡(公交卡)的内容,例如查看我还剩下多少张票。

我已经使用各种NFC应用程序扫描了该卡,并知道该卡的类型为:IsoDep和NfcB。

目前,我正在尝试使用IsoDep读取其内容,但没有成功(错误代码6A82、91AE、6E00等)。

我有一个应用程序在等待类型为“ACTION_NDEF_DISCOVERED || ACTION_TECH_DISCOVERED || ACTION_TAG_DISCOVERED”的新意图,它会打开一个新线程(因为不可能在UI线程上进行读取和连接),并尝试读取卡片的内容。

我猜我的问题在于我传递给isoDep.transceive(NATIVE_SELECT_APP_COMMAND)的字节。

我应该继续在IsoDep上尝试,还是应该尝试NfcB?你们有什么建议吗?

以下是我的代码示例:

 final byte[] SELECT = {
            (byte) 0x00, // CLA Class
            (byte) 0xA4, // INS Instruction
            (byte) 0x04, // P1  Parameter 1
            (byte) 0x00, // P2  Parameter 2
            (byte) 0x08, // Length
            (byte) 0x31,  (byte)0x54, (byte)0x49, (byte)0x43, (byte)0x2e,
            (byte) 0x49, (byte)0x43, (byte)0x41, // AID 315449432e494341
    };
Tag tagFromIntent = m_intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
IsoDep isoDep = IsoDep.get(tagFromIntent);
try {
    isoDep.connect();
    byte[] result = isoDep.transceive(SELECT);
    String str = bytesToHex(result);
    Log.i("test", "SELECT: " + str);
    isoDep.close();
} catch (Exception e) {
    String error = e.getMessage();
}

我的字节转十六进制函数:
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

=============================================================

编辑:

我刚刚了解到这张卡正在使用Calypso身份验证方案。

在这个问题的答案中有些帮助:Read data from NFC tag (IsoDep)。我找到了一个好的SELECT函数,我已经编辑了我的问题以持有新的“SELECT”命令,它正在工作——我得到了这个字符串:“6F228408315449432E494341A516BF0C13C70800000000029780A55307060A07062004019000”,但我不知道它是什么意思。

然后我使用这个命令尝试读取一个字符串:

byte[] GET_STRING = {
                (byte) 0x80, // CLA Class
                0x04, // INS Instruction
                0x00, // P1  Parameter 1
                0x00, // P2  Parameter 2
                0x10  // LE  maximal number of bytes expected in result
        };

但是我遇到了6E00错误,有什么建议吗?

дҪ зЎ®е®ҡеңЁе“Қеә”жӯӨе‘Ҫд»Өж—¶иҺ·еҫ—зҠ¶жҖҒз Ғ91AEжҲ–9100еҗ—пјҹеҰӮжһңжҳҜпјҢиҜ·зЎ®дҝқеҚЎзүҮжҳҜNfcBиҖҢдёҚжҳҜNfcAгҖӮ - Michael Roland
@MichaelRoland,嗨,我100%确定我得到了这些错误响应作为我的字符串的输出结果。其次,我已经使用另一个应用程序检查了这张卡片,它说它是NfcB,但无论如何,既然我正在尝试将其读取为IsoDep,那么它是A型还是B型有什么关系呢?只是问一下... - eladyanai
@MichaelRoland 我有一些进展,现在我遇到了6E00错误。 - eladyanai
不,您的卡片是NfcA或NfcB并不重要。然而,命令“90 5A 00 00 …”和状态字“91 00” /“91 AE”的组合表明这是一张DESFire卡片(因此应该是NfcA)。因此,由于您的卡现在响应选择“1TIC.ICA”DF,它肯定是一张Calypso卡,并且不应该用以上状态码进行响应。 - Michael Roland
@MichaelRoland 谢谢你,你是对的,我搞错了错误代码 - 很棒的发现!!! 我想我在查看错误代码时从其他地方复制粘贴时遇到了麻烦。无论如何。感谢你花时间帮助我! 下面的答案确实帮了我大忙,我只需要弄清楚如何从卡中实际读取信息。 - eladyanai
2个回答

5
你可以使用IsoDep与卡通信。
如果没有卡的规格说明,你想要访问卡上的数据,有两种方法:
1. 获取卡的规格说明(如何与之通信); 2. 进行逆向工程,这需要很长时间,并且不能保证结果,而且你可能会“锁定”对卡的访问。
更新1:
要读取Rav Kav卡,有一个开源项目:http://pannetrat.com/Cardpeek/ Rav Kav的代码在这里:https://code.google.com/p/cardpeek/source/browse/trunk/dot_cardpeek_dir/scripts/calypso/c376n3.lua

嘿,不确定我在哪里可以获取此卡的规格,因为它是一张地方公交公司的卡,我不认为他们会公开发布。有一些应用程序可以完全满足我的需求,它们是由私人构建的,所以我知道这是可能的。我只是想学习如何自己做。那么,你提到的逆向工程是什么意思?我没有问题“锁定”这张卡,因为它是一张虚拟卡,可以免费获得新卡。 - eladyanai
请提供以下信息:国家、城镇、公交公司名称、其他执行此任务的应用程序的网址... - LaurentY
谢谢你的帮助-这张卡在以色列被称为Rav Kav。当我在寻找信息来回答你时,我发现这张卡使用Calypso认证方案,我不知道它是什么意思-我计划进行调查-但如果你有任何见解,我会很乐意听取,干杯! - eladyanai
首先-哇!非常感谢!我还没有接受答案,因为它没有完全解决问题,我需要弄清楚如何正确使用isoDep.transceive以获取正确的信息,一旦我这样做了,我肯定会接受你的答案+我会发布更新,所以任何跟随我的人都可以读取这些卡片。再次感谢! - eladyanai
@eladyanai22 这有用吗? - LaurentY

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接