【问题标题】:Android NFC read from tag type: IsoDep and NfcBAndroid NFC 从标签类型读取:IsoDep 和 NfcB
【发布时间】:2015-10-26 01:16:27
【问题描述】:

我对 Android 开发和 NFC 非常陌生。

我正在尝试构建一个应用程序来读取 NFC 卡的内容,而我对这张卡(公交卡)一无所知,例如我想看看我还剩下多少张车票。

我已经使用各种 NFC 应用程序扫描了该卡,并且知道该卡的类型为:IsoDep AND 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”命令 - 作为回报,我得到了这个字符串:“6F228408315449432E494341A516BF0C13C708000000000029780A55307060A07062004019000”我不知道它是什么意思。

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

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,关于如何继续的任何想法?

【问题讨论】:

  • 您确定收到状态码91AE9100 以响应此命令吗?如果是,您确定该卡是 NfcB 而不是 NfcA?
  • @MichaelRoland,嘿,我 100% 确定我将这些错误响应作为字符串的输出结果。其次,我用另一个应用程序检查了这张卡,它说它是NfcB,但无论如何,因为我试图将它读取为IsoDep,它是A型还是B型有什么关系?只是问...
  • @MichaelRoland 我有一些进展,现在我收到错误 6E00
  • 不,您的卡是 NfcA 还是 NfcB 并不重要。但是,命令90 5A 00 00 ... 和状态字91 00 / 91 AE 的组合表明这是一张DESFire 卡(因此是NfcA)。因此,当您的卡现在响应选择 1TIC.ICA DF 时,它肯定是 Calypso 卡,不应该响应上述状态代码。
  • @MichaelRoland 谢谢你,你是对的,我弄错了错误代码-很好!我想我在查看错误代码时遇到了其他地方的复制粘贴问题。反正。感谢您花时间帮助我!下面的答案对我很有帮助,我只需要弄清楚如何从卡片中读取信息。

标签: android android-intent nfc


【解决方案1】:

您发送了错误的命令来读取应用程序的记录。 6E00 表示不正确的 INS 字节。

您可以查看这个 github,它会从基于 Calypso 规范的 MOBIB 卡中读取一些计数器。

https://github.com/flamingokweker/Android-NFC-Mobib-Reader

【讨论】:

    【解决方案2】:

    您可以通过 IsoDep 与卡通信。

    你想在没有本卡规格的情况下访问卡上的数据,有两种方式:

    • 获取卡的规格(如何与之通信)
    • 做逆向工程,这将花费大量时间并且不确定结果,并且您可以“锁定”对卡的访问权限

    更新 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

    【讨论】:

    • 嘿,我不知道从哪里可以得到这张卡的规格,因为它是当地的巴士公司卡,我不相信他们会发布它。很少有应用程序可以完全满足我的要求,而且它们是由私人构建的,所以我知道这是可能的。我只是想学习如何自己做。那么,您提到的逆向工程是什么?我“锁定”卡没有问题,因为它是一张虚拟卡,可以免费获得新卡。
    • 请给我信息:国家、城镇、公交公司名称、其他应用程序的网址...
    • 感谢您的帮助-该卡在以色列称为 Rav Kav,而我正在寻找信息以回答您的问题时发现该卡使用的是 Calypso 身份验证方案,我不知道是什么这意味着-我正计划调查-但如果您有任何见解,我很乐意领导,干杯!
    • 首先——哇!多谢!我还没有接受答案,因为它并没有从字面上解决问题,我需要弄清楚如何正确使用isoDep.transceive以获得正确的信息,一旦我这样做了,我一定会接受你的答案+我将发布更新,以便我之后的任何人都可以阅读这些卡片。再次,谢谢!
    • @eladyanai22 有用吗?
    猜你喜欢
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 2019-06-06
    相关资源
    最近更新 更多