java 使用 javax.smartcardio 从 mifare classic 读取块
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12011726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading block from mifare classic using javax.smartcardio
提问by Md. Sajedul Karim
I would like to read a specific block on Mifare classic using Java's javax.smartcardio. Here's my code:
我想使用 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[] {};
}
This method (sample found on internet) successfully reads the UID of the card, but when I try to construct my own command, I always become error SW1=63.
这个方法(网上找的例子)成功读取了卡的UID,但是当我尝试构建自己的命令时,总是出现错误SW1=63。
On this site (http://www.acs.com.hk/drivers/eng/API_ACR122U_v2.00.pdf) i have found some informations about APDU, but nothing is working and i cannot find out why. I have tried following command without success (always error 63): FF B0 00 04 10 (B0 - read binary block, 04 - number of sector, 10 - read 16 bytes). I have also tried reading only one byte, reading value block (INS B1) but also no success.
在这个网站 (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 ... (from my example) should be a direct transmit, but i don't know following instructions for reading a block.
FF 00 00 00 ...(来自我的示例)应该是直接传输,但我不知道遵循读取块的说明。
Can anyone help me? Thanks a lot. (Sorry for my english)
谁能帮我?非常感谢。(对不起我的英语不好)
回答by Md. Sajedul Karim
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):
在 Mifare Classic 1K 标签中有 16 个扇区,每个扇区包含 4 个块,每个块包含 16 个字节。从页面读取或写入之前 您必须使用密钥 A 或密钥 B 对扇区进行身份验证。当身份验证完成后,您就可以读取或写入。这是使用该密钥作为密钥 A (60) 验证扇区 0 的身份验证命令:
FF 86 0000 05 01 0000 60 00
Or authenticate sector 0 using that key as key B(61):
或者使用该密钥作为密钥 B(61) 验证扇区 0:
FF 86 0000 05 01 0000 61 00
or using this command you can also authenticate sector 0
或使用此命令您还可以验证扇区 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 };
When Authentication is succes then you will get 90 00. That is Success message. Else response is 63 00 , that means authentication failed. When Authentication complete then you can read block (0,1,2,3) cause sector 0 contains 4 block and those are block (0,1,2,3).
当身份验证成功时,您将收到 90 00。这是成功消息。否则响应为 63 00 ,这意味着身份验证失败。身份验证完成后,您可以读取块 (0,1,2,3),因为扇区 0 包含 4 个块,而这些块是块 (0,1,2,3)。
Using this command You can read data from Sector 0 block 1
使用此命令您可以从 Sector 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 };
Here last (byte) 0x01 is block where you want to read. in this answeryou can find the complete code. Just replace the byte value using this. Thanks.
这里最后一个(字节)0x01 是您要读取的块。 在这个答案中,您可以找到完整的代码。只需使用此替换字节值。谢谢。