【问题标题】:Reading block from mifare classic using javax.smartcardio使用 javax.smartcardio 从 mifare 经典中读取块
【发布时间】:2015-01-31 23:54:34
【问题描述】:

我想使用 Java 的 javax.smartcardio 阅读有关 Mifare classic 的特定块。 这是我的代码:

public byte[] getCardUID() throws CardException {
    CardTerminals terminals = TerminalFactory.getDefault().terminals();
    terminal = terminals.list().get(0);
    Card card = terminal.connect("*");
    CardChannel channel = card.getBasicChannel();
    CommandAPDU command = new CommandAPDU( new byte[] { (byte) 0xFF, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0xD4, (byte) 0x4A, (byte) 0x01, (byte) 0x00 });
    ResponseAPDU response = channel.transmit(command);
    card.disconnect(true);
    if (response.getSW1() == 0x90) {
        byte[] data = response.getData();
        data = Arrays.copyOfRange(data, 0x08, data.length);
        return data;
    }
    return new byte[] {};
}

这个方法(网上找的示例)成功读取了卡的UID,但是当我尝试构建自己的命令时,总是报错SW1=63。

在这个网站 (http://www.acs.com.hk/drivers/eng/API_ACR122U_v2.00.pdf) 我找到了一些关于 APDU 的信息,但没有任何工作,我不知道为什么。 我尝试了以下命令但没有成功(总是错误 63): FF B0 00 04 10(B0 - 读取二进制块,04 - 扇区数,10 - 读取 16 个字节)。我也试过只读取一个字节,读取值块(INS B1)但也没有成功。

FF 00 00 00 ...(来自我的示例)应该是直接传输,但我不知道遵循读取块的说明。

谁能帮助我?非常感谢。 (对不起我的英语)

【问题讨论】:

  • 您实际上是在使用 ACR122U,对吧?
  • 是的,我不能 100% 确定,因为我还没有安装这个驱动程序,但我想我正在使用 acr122u。顺便提一句。我的读者是touchatag。
  • 好的,据我所知,您应该能够使用这些专有的 APDU 与您的 mifare 通信,因此您原则上应该能够使用 javax.smartcardio 来执行此操作。也许流量将流向内部 SAM 智能卡而不是 mifare 卡?如果您打开阅读器,它是否包含接触式智能卡?
  • 我想,这应该是可能的,因为 UID 读取成功。我在阅读器上看不到任何螺丝刀,老实说,我宁愿让阅读器不打开。我试图找到一些技术细节,但没有成功。理论上,如果redaer有一个内部SAM智能卡,这意味着什么,在通信上有什么区别?
  • 所以,我发现,在我的阅读器中,有一张接触式智能卡,看起来像手机中的 SIM 卡。

标签: java mifare


【解决方案1】:

在 Mifare Classic 1K 标签中有 16 个扇区,每个扇区包含 4 个块,每个块包含 16 个字节。 从页面读取或写入之前您必须使用密钥 A 或密钥 B 验证扇区。验证完成后,您可以读取或写入。 这是身份验证命令 使用该密钥作为密钥 A (60) 验证扇区 0:

FF 86 0000 05 01 0000 60 00

或使用该密钥作为密钥 B(61) 验证扇区 0:

FF 86 0000 05 01 0000 61 00

或者使用这个命令你也可以验证扇区 0

byte[] authenticationByte = new byte[10];
authenticationByte = new byte[] { (byte) 0xFF, (byte) 0x86, (byte) 0x00,
 (byte) 0x00, (byte) 0x05, (byte) 0x00,(byte) 0x00, (byte) 0x04, 
                                    (byte) 0x60,(byte) 0x00 };

当身份验证成功时,您将获得 90 00。那是成功消息。否则响应为 63 00 ,表示身份验证失败。 身份验证完成后,您可以读取块 (0,1,2,3),因为扇区 0 包含 4 个块,它们是块 (0,1,2,3)。

使用这个命令你可以从Sector 0 block 1中读取数据

byte[] readFromPage = new byte[10];
readFromPage = new byte[] { (byte) 0xFF, (byte) 0x00, (byte) 0x00,
 (byte) 0x00, (byte) 0x05, (byte) 0xD4, (byte) 0x40,
 (byte) 0x00, (byte) 0x30, (byte) 0x01 };

最后(字节)0x01 是您要读取的块。 in this answer你可以找到完整的代码。只需使用此替换字节值。 谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多