如何将数据写入mifare经典标签

时间:2014-09-15 05:26:45

标签: c nfc mifare apdu

我正致力于NFC(Mifare经典标签)。我想知道如何将数据写入mi fare经典标签。我有空标签。请告诉我需要用于mifare经典标签的APDU命令。

我发送的APDU命令如下:

\x00','\xA4', '\x04', '\x00','\x07','\xd2','\x76','\x00','\x00','\x85','\x01','\x00

如果我使用这个apdu命令,它没有给出任何成功响应(因为每个APDU命令将有9000)它进入else部分。请告诉我正确的apdu命令。我正在用C语言编写代码。我的读者是MFC 523.需要遵循的步骤是什么?

// code i am using its for the Mobile POS 

   int ret;
   sendtoUSB("going to the auth",17); // for display purpose 
   // for authentication we will use the basic  authentication between the reader and writer 
      Sys_ClearScreen();
      char cRecvBuf[128];
      int  i,j;      
      char cSendBuf[10]= {0xFF,0x86,0x00,0x00,0x05,0x01,0x00,0x05,0x60,0x01};     // authenticaton key 
      char msg[128];
      u32  rlen; // response length 
      Sys_PcdOpen();
      while(1)
      {
          sendtoUSB("in while",8);
          if(Sys_Kbhit()==KEY_CANCEL)
             break;

          ret = Sys_PiccPresent();

          // activation of the NFC
          ret = Sys_PiccActivate();


          uchar key[16]= {0xFF,0x82,0x20,0x01,0x06,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF} ; //Load keys command 

          char cSendBuf[10]= {0xFF,0x86,0x00,0x00,0x05,0x01,0x00,0x05,0x60,0x01};   // authentication command 

          ret = Sys_PiccCommand(key,11,&rlen,cRecvBuf); // sending the command 
          sendtoUSB("In send cmd",11);

          sendtoUSB(key,strlen(key)); // here i am getting the key as i am sending 


          sendtoUSB(cRecvBuf,rlen);  // in recvbuf i am agetting as 6E00



          if(ret==0) // checking the returing value 
          {
              // its coming into the if also 
              sendtoUSB("sucess",6);
              if(rlen>=0)
              {
                 if((cRecvBuf[rlen-2]==0x90) && (cRecvBuf[rlen-1]==0x00)) // checking the 90 00 response 

                 {
                      // not coming here
                      sendtoUSB("in if",5); 
                    strcpy(msg, "ankita"); 
                    for(i=0;i<rlen-2;i++)
                      sprintf(msg+strlen(msg), "%02X", cRecvBuf[i]);

                    Sys_DisplayLine( 2, msg, 0, ALIGN_LEFT) ;

                 }
                 else
                 {
                     // its coming here 

                    sendtoUSB("In else",7);



                    sprintf(msg, "In else 02X%02X", cRecvBuf[rlen-2],cRecvBuf[rlen-1]);


                    Sys_DisplayLine( 2, msg, 1, ALIGN_CENTER) ;
                    sendtoUSB ("fail data",9);
                    sendtoUSB(cRecvBuf,rlen);
                    sendtoUSB(msg,strlen(msg));

                }
            }

        }
        Sys_PiccDeselect(RM_WAIT);
        break;
    }
    Sys_PcdClose();
    Sys_WaitReturn();

    Sys_Buzzer(KB_BEEP_DURATION);



}


// i am following the same steps for the authentication also


//open NFC
// check NFC is there or not 
//activate 
// send command 

2 个答案:

答案 0 :(得分:1)

我认为,&#34;加载键命令&#34;中存在问题。这里我发布了加载密钥命令结构。

enter image description here

答案 1 :(得分:0)

您是否以此格式发送身份验证ADPU命令?如果没有,请尝试以下操作。它在MIFARE Classic标签认证中适用于我。

GENERAL AUTHENTICATE command APDU

    CLA     INS     P1      P2      Lc      DATAin          Le
    0xFF    h86     00      00      05      seebelow        -
    (def.)  (for 
            authent-
            ication 
            cmmd)

            GENERAL AUTHENTICATE Data In bytes

    Byte 0          Byte 1          Byte2           Byte3           Byte4
    h01             h00             Block            key            key     
                                    number          location        index
                                                    or Key 
                                                    type 

块号(BYTE 2)是卡上的地址,我们尝试进行身份验证(块号)

密钥位置或密钥类型(BYTE 3)必须是:

  • h60,使用CRYPTO1“A”键进行认证(标准PC / SC定义值),
  • h61使用CRYPTO1“B”键进行认证(标准PC / SC定义值),

与LOAD KEY指令中使用的P1参数值相同:h00或h20(SpringCard 具体价值)。

密钥索引(字节4)定义如下:

  • 如果密钥类型(字节3)是h60,使用值h00到h03选择存储在阅读器中的一个“A”键 易失性存储器,值h20到h2F,用于选择存储在阅读器非易失性存储器中的一个“A”键(如果有)。

  • 如果密钥类型(字节3)是h61,使用值h00到h03选择存储在阅读器中的一个“B”键 易失性存储器,值h20到h2F,用于选择存储在阅读器非易失性存储器中的一个“B”键(如果有)。


int PCSC_Mifare_Read (unsigned char *data, unsigned int read_size, unsigned char block_num)
{
  unsigned char TxBuffer[5]= {0xFF, 0xB0};
  unsigned char RxBuffer[42]= {0};
  int Response = -1;
  int SendLength = 0;
  unsigned long RecvLength = 0;

  if (data == NULL)
  {
        Debug(__func__,"Invalid Param");
    return Response;
  }

  if (0xFF > block_num)
  {
    TxBuffer[2] = 0x00;
    TxBuffer[3] = block_num;
  }
  else
  {
    /* If the block number is greater than 0xFF then store the block number's MSB in P1 field
       and LSB in P2 field of APDU*/
    TxBuffer[2] = (block_num % 0xFF);
    TxBuffer[3] = 0xFF;
  }

  TxBuffer[4] = read_size; //or 0x00 or 0x20 if card supports 32 BYTE data read

  SendLength = sizeof (TxBuffer);
  RecvLength = sizeof (RxBuffer);

  Response = SCardTransmit(hCard, pioSendPci, TxBuffer, SendLength,
                           &pioRecvPci, RxBuffer, &RecvLength);
  if (Response != SCARD_S_SUCCESS)
  {
    Debug (__func__,"SCardTransmit Failed: %s 0x%x",pcsc_stringify_error(Response), Response);
    return Response;
  }

  if ((RxBuffer[RecvLength-2] == 0x90) && (RxBuffer[RecvLength-1] == 0x00))
  {
    Debug (__func__,"Succeeded : %02x %02x",RxBuffer[RecvLength-2], RxBuffer[RecvLength-1]);

    if (RecvLength > 0x02)
    {
        memcpy (data, RxBuffer, (RecvLength-2));
                Debug(__func__,"Read passed");
    }
    else
    {
                Debug(__func__,"Read Failed");
                return -1;
    }
  }
  else
  {
     Debug(__func__,"Failed : %02x %02x",RxBuffer[RecvLength-2], RxBuffer[RecvLength-1]);
     return -1;
  }

  return Response;
}


int PCSC_Mifare_Write (unsigned char block_num, unsigned char *data,unsigned int size)
{
  unsigned char TxBuffer[21] = {0xFF, 0xD6};
  unsigned char RxBuffer[2] = {0};
  int Response = -1;
  int SendLength = 0;
  unsigned long RecvLength = 0;

  if (0xFF > block_num)
  {
    TxBuffer[2] = 0x00;
    TxBuffer[3] = block_num;
  }
  else
  {
    /* If the block number is greater than 0xFF then store the block number's MSB in P1 field
       and LSB in P2 field of APDU*/
    TxBuffer[2] = (block_num % 0xFF);
    TxBuffer[3] = 0xFF;
  }

  TxBuffer[4] = size; //This is the block size to be written

  //copy the 0x08 BYTE data to be writen to the card
  memcpy ((TxBuffer + 5), data, size);

  SendLength = 5+size;//sizeof (TxBuffer);
  RecvLength = sizeof (RxBuffer);

//  HexDump("PCSC_Mifare_Write", TxBuffer, SendLength);

  Response = SCardTransmit(hCard, pioSendPci, TxBuffer, SendLength,
                           &pioRecvPci, RxBuffer, &RecvLength);
  if (Response != SCARD_S_SUCCESS)
  {
    Debug (__func__,"SCardTransmit Failed: %s 0x%x",pcsc_stringify_error(Response), Response);
    return Response;
  }

  if ((RxBuffer[0] == 0x90) && (RxBuffer[1] == 0x00))
  {
    Debug (__func__,"Succeeded : %02x %02x",RxBuffer[0],RxBuffer[1]);
  }
  else
  {
    Debug (__func__,"Failed : %02x %02x",RxBuffer[0],RxBuffer[1]);
    return -1;
  }

  return Response;
}