使用javax.smartcardio从mifare classic中读取块

4 java mifare

我想使用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[] {};
}
Run Code Online (Sandbox Code Playgroud)

这个方法(在互联网上找到的样本)成功读取卡的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 ...(来自我的例子)应该是直接传输,但我不知道以下读取块的指令.

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

Md.*_*rim 6

In Mifare Classic 1K tags There are 16 Sectors and each Sectors contains 4 Blocks and each block contains 16 bytes. Before Reading or writing from a page You must have to Authenticate The Sector using Key A or Key B. When Authentication is complete then you can read or write. Here is the Authentication Command Authenticate sector 0 using that key as key A (60):

FF 86 0000 05 01 0000 60 00
Run Code Online (Sandbox Code Playgroud)

Or authenticate sector 0 using that key as key B(61):

FF 86 0000 05 01 0000 61 00
Run Code Online (Sandbox Code Playgroud)

or using this command you can also authenticate sector 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 };
Run Code Online (Sandbox Code Playgroud)

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

使用此命令您可以从扇区0块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 };
Run Code Online (Sandbox Code Playgroud)

最后(字节)0x01是您要读取的块. 在这个答案中,您可以找到完整的代码.只需用这个替换字节值.谢谢.