![](/img/trans.png)
[英]How to Control LED on ACR122 using smartcardio and Java?
[英]ACR122 and javax.smartcardio for nfc
我是一名学生,作为实习的一部分,我希望制作一个能使我从ACR122阅读器读取nfc标签的小程序。 我使用包javax.smartcardio。 但是,我无法读取在标签甚至uid上找到的数据。 传输方法向我返回了许多我不太了解的数据,而且完全是随机的。 我认为不要在CommandAPDU对象中使用好的十六进制值。
我的线程的run方法的代码:
结果如下:
ResponseAPDU:ResponseAPDU:2字节,SW = 6300
ResponseAPDU getBytes:[B @ 5c12c55c
ResponseAPDU getData:[B @ 6c63e398
ResponseAPDU:ResponseAPDU:2字节,SW = 6300
ResponseAPDU getBytes:[B @ 5c12c55c
ResponseAPDU getData:[B @ 6c63e39
更新
现在,我可以读取卡上的数据,但是只有当它们为空时,当我使用其他应用程序(例如GoToTag)在其上写入数据时,我才能对块进行身份验证。 而且我也不能写。
这是我要阅读的代码:
if(MyReader.waitForCardPresent(0))
{
if(!Lu)
System.out.println("détectée");
card = MyReader.connect("*");
if(card != null)
{
if(!Lu)
{
System.out.println("Carte connectée");
System.out.println("ATR: " + arrayToHex(((ATR) card.getATR()).getBytes()));
}
ch = card.getBasicChannel();
/*Get UID*/
byte[] ApduArrayUID = {
(byte) 0xff,
(byte) 0xca,
(byte) 0x00,
(byte) 0x00,
(byte) 0x00
};
/*Iso Card*/
byte[] ApduArrayISO = {
(byte) 0xff,
(byte) 0xca,
(byte) 0x01,
(byte) 0x00,
(byte) 0x00
};
/* load Authentification */
byte[] ApduArrayLoadAuth= {
(byte) 0xff, //Class
(byte) 0x82, //INS
(byte) 0x00,//emplacement volatile du lecteur
(byte) 0x00, //emplacement sur le lecteur
(byte) 0x06, //LC
(byte) 0xff, // Valeur de la clé sur 6 bytes
(byte) 0xff,
(byte) 0xff,
(byte) 0xff,
(byte) 0xff,
(byte) 0xff
};
/*Authentication du Block 00h*/
byte[] ApduArrayAuth = {
(byte) 0xff,// Class
(byte) 0x86, //INS
(byte) 0x00,//P1
(byte) 0x00,//P2
(byte) 0x05,//LC
//Authentication Data bytes
(byte) 0x01, //Version
(byte) 0x00, // Byte 2
(byte) 0x00,//Block number
(byte) 0x60,// Clé de type A
(byte) 0x00 //Emplacement de la clé
};
/*Read Block 1*/
byte[] ApduArrayRead = {
(byte) 0xff, //Class
(byte) 0xb0,//INS
(byte) 0x00,//P1
(byte) 0x00,//P2 = Block number
(byte) 0x10, // Le = Number of bytes to read
};
/***** UID *****/
CommandAPDU GetDataUID = new CommandAPDU(ApduArrayUID);
ResponseAPDU CardApduResponseUID = ch.transmit(GetDataUID);
//nfc.AfficheUID(byteToString(CardApduResponseUID.getBytes()));
if(CardApduResponseUID.getSW() == 36864)
{
String Uid=byteToString(CardApduResponseUID.getBytes());
if(! Uid.equals(UidCourant))// Si une nouvelle carte les blocks mémoire ne sont pas authentifié
{
Auth=false;
Lu=false;
}
else
{
Auth=true; Lu=true;
}
UidCourant= byteToString(CardApduResponseUID.getBytes());
uid.setText(UidCourant);
if(!Lu)
System.out.println("UID : "+UidCourant);
}
/***** Charger authentification *****/
//System.out.println("UID response: " + byteToString(CardApduResponseUID.getBytes()));
if(!Charge)
{
System.out.println("Chargement de l'authentification dans le lecteur ");
CommandAPDU GetDataLoadAuth = new CommandAPDU(ApduArrayLoadAuth);
ResponseAPDU CardApduResponse = ch.transmit(GetDataLoadAuth);
if(CardApduResponse.getSW() == 36864) // 90 00h = success
{
Charge=true;
System.out.println("Chargement authentification réussie :" );
}
}
if(Charge)
{
if(!Auth)
{
/******* authentification du block 00h*********/
System.out.println("Authentification d'un block");
CommandAPDU GetDataAuth = new CommandAPDU(ApduArrayAuth);
ResponseAPDU CardApduResponseAuth = ch.transmit(GetDataAuth);
System.out.println("ResponseAPDU auth : "+ CardApduResponseAuth);
if(CardApduResponseAuth.getSW() == 36864)
{
Auth=true;
System.out.println("Authentification d'un block réussie ! ");
}
else
System.out.println("Impossible d'authentifier le block :'(");
}
if(Auth && !Lu) // si l'authentification est faite et qu'on a pas encore Lu, on lit
{
/*Lecture du block 0x00*/
System.out.println("Lecture d'un block");
CommandAPDU GetDataRead = new CommandAPDU(ApduArrayRead);
ResponseAPDU CardApduResponseRead = ch.transmit(GetDataRead);
System.out.println("ResponseAPDU auth : "+ CardApduResponseRead);
if(CardApduResponseRead.getSW() == 36864)
{
System.out.println("Read response: " + byteToString(CardApduResponseRead.getBytes()));
Lu=true;
}
}
}
card.disconnect(true);
}
else
System.out.println("Carte non connectée");
}
这是我要编写的代码:
while(!isStop())
{
try
{
uid.setText("");
if(MyReader.waitForCardPresent(0))
{
if(!Lu)
System.out.println("détectée");
card = MyReader.connect("*");
if(card != null)
{
if(!Lu)
{
System.out.println("Carte connectée");
System.out.println("ATR: " + arrayToHex(((ATR) card.getATR()).getBytes()));
}
ch = card.getBasicChannel();
/*Get UID*/
byte[] ApduArrayUID = {
(byte) 0xff,
(byte) 0xca,
(byte) 0x00,
(byte) 0x00,
(byte) 0x00
};
/*Iso Card*/
byte[] ApduArrayISO = {
(byte) 0xff,
(byte) 0xca,
(byte) 0x01,
(byte) 0x00,
(byte) 0x00
};
/* load Authentification */
byte[] ApduArrayLoadAuth= {
(byte) 0xff, //Class
(byte) 0x82, //INS
(byte) 0x00,//emplacement volatile du lecteur
(byte) 0x00, //emplacement sur le lecteur
(byte) 0x06, //LC
(byte) 0xff, // Valeur de la clé sur 6 bytes
(byte) 0xff,
(byte) 0xff,
(byte) 0xff,
(byte) 0xff,
(byte) 0xff
};
/*Authentication du Block 00h*/
byte[] ApduArrayAuth = {
(byte) 0xff,// Class
(byte) 0x86, //INS
(byte) 0x00,//P1
(byte) 0x00,//P2
(byte) 0x05,//LC
//Authentication Data bytes
(byte) 0x01, //Version
(byte) 0x00, // Byte 2
(byte) 0x00,//Block number
(byte) 0x60,// Clé de type A
(byte) 0x00 //Emplacement de la clé
};
/*Write Block 1*/
byte[] ApduArrayWrite = {
(byte) 0xff, //Class
(byte) 0xd6,//INS
(byte) 0x00,//P1
(byte) 0x00,//P2 = Block number
(byte) 0x02, // Lc = Number of bytes to update
//Data to be written
(byte)0x00,
(byte)0x01
};
/***** UID *****/
CommandAPDU GetDataUID = new CommandAPDU(ApduArrayUID);
ResponseAPDU CardApduResponseUID = ch.transmit(GetDataUID);
//nfc.AfficheUID(byteToString(CardApduResponseUID.getBytes()));
if(CardApduResponseUID.getSW() == 36864)
{
String Uid=byteToString(CardApduResponseUID.getBytes());
if(! Uid.equals(UidCourant))// Si une nouvelle carte les blocks mémoire ne sont pas authentifié
{
Auth=false;
Lu=false;
}
else
{
Auth=true; Lu=true;
}
UidCourant= byteToString(CardApduResponseUID.getBytes());
uid.setText(UidCourant);
if(!Lu)
System.out.println("UID : "+UidCourant);
}
/***** Charger authentification *****/
//System.out.println("UID response: " + byteToString(CardApduResponseUID.getBytes()));
if(!Charge)
{
System.out.println("Chargement de l'authentification dans le lecteur ");
CommandAPDU GetDataLoadAuth = new CommandAPDU(ApduArrayLoadAuth);
ResponseAPDU CardApduResponse = ch.transmit(GetDataLoadAuth);
if(CardApduResponse.getSW() == 36864) // 90 00h = success
{
Charge=true;
System.out.println("Chargement authentification réussie :" );
}
}
if(Charge)
{
if(!Auth)
{
/******* authentification du block 00h*********/
System.out.println("Authentification d'un block");
CommandAPDU GetDataAuth = new CommandAPDU(ApduArrayAuth);
ResponseAPDU CardApduResponseAuth = ch.transmit(GetDataAuth);
System.out.println("ResponseAPDU auth : "+ CardApduResponseAuth);
if(CardApduResponseAuth.getSW() == 36864)
{
Auth=true;
System.out.println("Authentification d'un block réussie ! ");
}
else
System.out.println("Impossible d'authentifier le block :'(");
}
if(Auth && !Lu) // si l'authentification est faite et qu'on a pas encore Lu, on lit
{
/*Ecriture du block 0x00*/
System.out.println("Ecriture d'un block");
CommandAPDU GetDataWrite = new CommandAPDU(ApduArrayWrite);
ResponseAPDU CardApduResponseWrite = ch.transmit(GetDataWrite);
System.out.println("ResponseAPDU Write : "+ CardApduResponseWrite);
if(CardApduResponseWrite.getSW() == 36864)
{
System.out.println("Ecriture réussite!");
System.out.println("Write response: " + byteToString(CardApduResponseWrite.getBytes()));
Lu=true;
}
else
System.out.println("Echec de l'écriture :/");
}
}
card.disconnect(true);
}
else
System.out.println("Carte non connectée");
}
您当前正在使用密钥A FF FF FF FF FF FF
向扇区0进行身份验证。 诸如GoToTags或NFC TagWriter之类的应用程序将根据NXP的应用笔记“ NFC Type MIFARE Classic Tag Operation ”将MIFARE Classic卡转换为NDEF标签。 结果,修改了扇区0(MIFARE应用程序目录扇区)和用于存储NDEF数据的扇区的访问条件。 通常,这意味着
A0 A1 A2 A3 A4 A5
(“ MAD密钥”),将密钥B设置为FF FF FF FF FF FF
,并且访问条件设置为只能使用密钥A键B可用于读取和写入。 D3 F7 D3 F7 D3 F7
,将密钥B设置为FF FF FF FF FF FF
,并设置访问条件,使得密钥A仅可用于读取,而密钥B仅可用于读取可用于阅读和写作。 因此,一旦使用了这样的应用程序,将不再使用密钥A FF FF FF FF FF FF
对扇区0进行身份验证,因此您必须相应地更新byte[] ApduArrayLoadAuth
命令定义中的密钥(或更改密钥类型)。 byte[] ApduArrayAuth
to key B)。
您在byte[] ApduArrayWrite
写命令byte[] ApduArrayWrite
当前尝试写两个字节:
byte[] ApduArrayWrite = { (byte) 0xff, //Class
(byte) 0xd6, //INS
(byte) 0x00, //P1
(byte) 0x00, //P2 = Block number
(byte) 0x02, // Lc = Number of bytes to update
//Data to be written
(byte)0x00, (byte)0x01 };
MIFARE Classic块由16个字节组成,因此只能写入两个字节。 您总是必须编写一个完整的块:
byte[] ApduArrayWrite = { (byte) 0xff, //Class
(byte) 0xd6, //INS
(byte) 0x00, //P1
(byte) 0x00, //P2 = Block number
(byte) 0x10, // Lc = Number of bytes to update
//Data to be written
(byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 };
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.