我被要求编写一个简单的程序来读取和写入数据从智能卡(mifare)使用nfc,但我卡住了。
我必须得到uid(到目前为止还不错),写一些数据从数据库中的一些块的卡(没有办法)。
我必须使用java和acr122阅读器。我写的代码仍然需要改进和重构一点,这主要是一个草案,但我想首先做的任务,然后修复一切。我在网上看到了我能找到的东西,但我还是错过了一些东西。到目前为止,我得到的(主要是整理一些代码)是:
package testnfc;
import javax.smartcardio.*;
import java.util.Arrays;
import java.util.List;
import static testnfc.Helpers.*;
import java.nio.ByteBuffer;
public class TestNFC {
`enter code here`public static void main(String[] args) throws CardException {
// get and print any card readers (terminals)
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals=null;
try{
terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
// work with the first terminal
CardTerminal term = terminals.get(0);
// connect with the card. Throw an exception if a card isn't present
// the * means use any available protocol
try{
Card card = term.connect("*");
System.out.println("card: " + card);
//Got the card
CardChannel channel = card.getBasicChannel();
byte[] instruction = hexToBytes("FF CA 00 00 00");
CommandAPDU getUID = new CommandAPDU(instruction);
ResponseAPDU response = channel.transmit(getUID);
String uid = bytesToPrettyHex(response.getData());
String status = bytesToPrettyHex(new byte[] {(byte)response.getSW1(), (byte)response.getSW2()});
System.out.printf("UID: %s\tResponse: %s\n", uid, status); //Status = 90 -> Success, 63 -> Fail
//Up to this point it works, I can get the terminal and the UID of the card. Now I am trying to write datas in the card
byte[] dati;
dati=new byte[4];
dati[0]=(byte)12;
dati[1]=(byte)12;
dati[2]=(byte)12;
writeData(card, (byte)1, dati);
}
catch(CardNotPresentException exc){
System.out.println("Card not found!");
}
}
catch(CardException ex){
System.out.println("Terminal not found!");
}
}
public static void writeData(Card c, byte block, byte[] data)
throws CardException {
byte cla = (byte) 0xFF;
byte ins = (byte) 0xD6;
byte p1 = (byte) 0x00;
byte p2 = block;
byte le = 0x10;
byte[] params = new byte[21];
for (int i = 0; i < 21; i++) {
params[i] = 0x20;
}
params[0] = cla;
params[1] = ins;
params[2] = p1;
params[3] = p2;
params[4] = le;
for (int i = 0; i < data.length; i++) {
params[5 + i] = data[i];
}
System.out.println("step1");
CardChannel channel = c.getBasicChannel();
CommandAPDU command = new CommandAPDU(params);
System.out.println("Step2");
ResponseAPDU response = channel.transmit(command);
System.out.println("Step3, response ->"+ response);
validateResponse(response);
System.out.println("Step4");
}
private static void validateResponse(ResponseAPDU response)
throws CardException {
int respSW1=0;
int respSW2=0;
respSW1 = response.getSW1();
respSW2 = response.getSW2();
System.out.println("SW1 ->"+respSW1 + ", SW2 ->"+ respSW2);
if (respSW1 != 144) {
throw new CardException("Autentication Problem?");
}
}
}
我得到的结果是
Terminals: [PC/SC terminal ACS ACR122 0]
card: PC/SC card in ACS ACR122 0, protocol T=1, state OK
UID: EA:54:42:AA Response: 90:00
step 1
step2
step3, response ->ResponseAPDU: 2 bytes, SW=6300
SW1 ->99, SW2 ->0
Terminal not found
我能读卡片的uid,但不能写;该卡本身是可以的,使用nfc工具的桌面我可以访问和写。我找了一些文件,但我不能解决问题,我不能正确地学习没有一些例子。我不明白为什么会得到6300代码:从我发现的情况来看,这意味着“非易失性内存的状态发生了变化”,但如果我用nfc工具检查,我找不到任何区别。
我需要改变什么才能从卡片上读写?
3条答案
按热度按时间w51jfk4q1#
一旦你知道这是什么卡,你就可以查看数据表https://www.nxp.com/docs/en/data-sheet/mf1s70yyx_v1.pdf 查看它的内存是如何构造的以及它支持哪些命令。
然后,如何从读取器的picc命令将它们 Package 到伪apdu中(第5节)https://www.acs.com.hk/download-manual/419/api-acr122u-2.04.pdf )
jaql4c8m2#
我解决了这个问题。这是我的代码(一个概念证明,只是为了说明它是如何工作的)
3mpgtkmj3#
根据nfc工具,它是mifare经典的1kb