0

私は学生で、インターンシップの一環として、ACR122 リーダーから nfc タグを読み取ることができるアプレットを作成しようとしています。パッケージ javax.smartcardio を使用します。ただし、タグまたは uid で見つかったデータを読み取ることができません。送信メソッドは、私が本当に理解していない多くのデータを返します...そして完全にランダムです。CommandAPDU オブジェクトに適切な 16 進数値を使用しないと思います。

私のスレッドの 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");

                        }
4

1 に答える 1

0

MIFARE Classic カードからのデータの読み取りは、空の状態でも可能ですが、別のアプリケーション (GoToTags など) がカードに書き込むと機能しません。

現在、キー A を使用してセクター 0 を認証していますFF FF FF FF FF FF。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 を使用したセクター 0 への認証は機能しFF FF FF FF FF FFなくなるため、それにbyte[] ApduArrayLoadAuth応じてコマンド定義のキーを更新する (またはキー タイプbyte[] ApduArrayAuthをキー B に変更する) 必要があります。

MIFARE Classic カードへの書き込みが機能しない

現在、書き込みコマンドはbyte[] ApduArrayWrite2 バイトを書き込もうとしています。

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 バイトで構成されているため、2 バイトだけを書き込むことはできません。常に完全なブロックを書く必要があります:

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 };
于 2015-03-19T07:23:51.720 に答える