繁体   English   中英

NFC的ACR122和javax.smartcardio

[英]ACR122 and javax.smartcardio for nfc

我是一名学生,作为实习的一部分,我希望制作一个能使我从ACR122阅读器读取nfc标签的小程序。 我使用包javax.smartcardio。 但是,我无法读取在标签甚至uid上找到的数据。 传输方法向我返回了许多我不太了解的数据,而且完全是随机的。 我认为不要在CommandAPDU对象中使用好的十六进制值。

我的线程的run方法的代码:

http://pastebin.com/u6m0jArd

结果如下:

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");

                        }

当MIFARE Classic卡为空时,可以从中读取数据,但是一旦另一个应用程序(如GoToTags)写入卡后,该数据将无法使用

您当前正在使用密钥A FF FF FF FF FF FF向扇区0进行身份验证。 诸如GoToTags或NFC TagWriter之类的应用程序将根据NXP的应用笔记“ NFC Type MIFARE Classic Tag Operation ”将MIFARE Classic卡转换为NDEF标签。 结果,修改了扇区0(MIFARE应用程序目录扇区)和用于存储NDEF数据的扇区的访问条件。 通常,这意味着

  • 对于扇区0,将密钥A设置为A0 A1 A2 A3 A4 A5 (“ MAD密钥”),将密钥B设置为FF FF FF FF FF FF ,并且访问条件设置为只能使用密钥A键B可用于读取和写入。
  • 对于所有其他扇区,将密钥A设置为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)。

写入MIFARE Classic卡不起作用

您在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM