I am a student and as part of my internship I am looking to make an applet that lets me read a nfc tag from the ACR122 reader. I use the package javax.smartcardio. However, I can not read the data found on the tag or even the uid. the transmit methode returns me many data that I do not really understand ... and completely random. I think not spend good hexadecimal values in my CommandAPDU object.
The code for the run method of my thread:
Here are the results:
ResponseAPDU : ResponseAPDU: 2 bytes, SW=6300
ResponseAPDU getBytes: [B@5c12c55c
ResponseAPDU getData: [B@6c63e398
ResponseAPDU : ResponseAPDU: 2 bytes, SW=6300
ResponseAPDU getBytes: [B@5c12c55c
ResponseAPDU getData: [B@6c63e39
UPDATE
right now I can read Data on the card but only when they are empty, when I write on it with another application (like GoToTag) I can't authenticate a block. Moreover I can't write on it neither.
Here is my code to read:
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");
}
Here is my code to write:
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");
}