2013-08-05 123 views
1

全部!Mifare讀取APDU命令recived 63 00

我想從mifare卡1k讀取數據。
得到ID
我發送:0xFF 0xCA 0x00 0x00 0x00
Recive:0x00 0x00 0x00 0x00 0x00 0x00 - ?這是正常的?

加載AUTH關鍵讀者
我送:爲0xFF爲0x82爲0x00爲0x00 0×06爲0xFF 0xFF的0xFF的0xFF的0xFF的0xFF的
Recive:90 00 - 這是確定

塊驗證01
我送:爲0xFF 0x86可以爲0x00爲0x00 0x05中0×01 0×00 0×01 0x60的0×00
Recive:90 00 - 這是確定

從塊讀取的數據01
我發送:0xFF的0XB0 0×00 0×01爲0x0F
Recive:63 00 - 如何理解它的身份驗證錯誤

我不明白 - 爲什麼?

我的代碼:

#include "stdafx.h" 
#include "Winscard.h" 

LPTSTR   pmszReaders = NULL; 
LPTSTR  pmszCards = NULL; 
LPTSTR   pReader; 
LPTSTR   pCard; 
LONG   lReturn, lReturn2; 
DWORD   cch = SCARD_AUTOALLOCATE; 
SCARDCONTEXT hSC; 
SCARD_READERSTATE readerState; 
LPCTSTR   readerName = L"ACS ACR1222 1S Dual Reader 0"; 
SCARDHANDLE  hCardHandle; 
DWORD   dwAP; 
BYTE   pbRecv[50]; 
DWORD   dwRecv; 

BYTE   cmdGetData[] = {0xFF, 0xCA, 0x00, 0x00, 0x00}; 
BYTE   cmdLoadKey[] = {0xFF, 0x82, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
BYTE   cmdAuthBlock01[] = {0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, 0x01, 0x60, 0x00}; 
BYTE   cmdReadBlock01[] = {0xFF, 0xB0, 0x00, 0x01, 0x0F}; 



int _tmain(int argc, _TCHAR* argv[]) { 

    lReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hSC); 
    if (SCARD_S_SUCCESS != lReturn) 
     printf("Failed SCardEstablishContext\n"); 
    else { 
     lReturn = SCardListReaders(hSC, NULL, (LPTSTR)&pmszReaders, &cch); 
     if (lReturn != SCARD_S_SUCCESS) { 
      printf("Failed SCardListReaders\n"); 
     } else { 
      pReader = pmszReaders; 
      while ('\0' != *pReader) { 
       printf("Reader: %S\n", pReader); 
       pReader = pReader + wcslen((wchar_t *)pReader) + 1; 
      } 
     } 

     memset(&readerState,0,sizeof(readerState)); 
     readerState.szReader = pmszReaders; 

     lReturn = SCardConnect(hSC, pmszReaders, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCardHandle, &dwAP); 
     if (SCARD_S_SUCCESS != lReturn) { 
      printf("Failed SCardConnect\n"); 
      system("pause"); 
      exit(1); 
     } else { 
      printf("Success SCardConnect\n"); 
      switch (dwAP) { 
       case SCARD_PROTOCOL_T0: 
        printf("Active protocol T0\n"); 
        break; 
       case SCARD_PROTOCOL_T1: 
        printf("Active protocol T1\n"); 
        break; 
       case SCARD_PROTOCOL_UNDEFINED: 
       default: 
        printf("Active protocol unnegotiated or unknown\n"); 
        break; 
      } 
     } 

     lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdGetData, sizeof(cmdGetData), NULL, pbRecv, &dwRecv); 
     if (SCARD_S_SUCCESS != lReturn) { 
      printf("Failed SCardTransmit\n"); 
     } else { 
      printf("Success SCardTransmit\n"); 
      printf("Read %u bytes\n", dwRecv); 
      for(byte i=0;i<dwRecv;i++) { 
       printf("%x ", pbRecv[i]); 
      } 
      printf("\n"); 
     } 


     lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdLoadKey, sizeof(cmdLoadKey), NULL, pbRecv, &dwRecv); 
     if (SCARD_S_SUCCESS != lReturn) { 
      printf("Failed SCardTransmit\n"); 
     } else { 
      printf("Success SCardTransmit\n"); 
      printf("Read %u bytes\n", dwRecv); 
      for(byte i=0;i<dwRecv;i++) { 
       printf("%x ", pbRecv[i]); 
      } 
      printf("\n"); 
     } 


     lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdAuthBlock01, sizeof(cmdAuthBlock01), NULL, pbRecv, &dwRecv); 
     if (SCARD_S_SUCCESS != lReturn) { 
      printf("Failed SCardTransmit\n"); 
     } else { 
      printf("Success SCardTransmit\n"); 
      printf("Read %u bytes\n", dwRecv); 
      for(byte i=0;i<dwRecv;i++) { 
       printf("%x ", pbRecv[i]); 
      } 
      printf("\n"); 
     } 


     lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdReadBlock01, sizeof(cmdReadBlock01), NULL, pbRecv, &dwRecv); 
     if (SCARD_S_SUCCESS != lReturn) { 
      printf("Failed SCardTransmit\n"); 
     } else { 
      printf("Success SCardTransmit\n"); 
      printf("Read %u bytes\n", dwRecv); 
      for(byte i=0;i<dwRecv;i++) { 
       printf("%x ", pbRecv[i]); 
      } 
      printf("\n"); 
     } 


    } 

    lReturn = SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD); 
    if (SCARD_S_SUCCESS != lReturn) { 
     printf("Failed SCardDisconnect\n"); 
    } else { 
     printf("Success SCardDisconnect\n"); 
    } 
    system("pause"); 
    return 0; 
} 

任何人都可以解釋爲什麼我有63 00? 謝謝。

+0

嘗試使用命令'88'而不是'86'進行驗證,然後讀取塊。一種可能的身份驗證APDU可以是:{{FF,88,00,00,01,60,00})。 –

回答

1

Afair您的read命令必須是:「0xFF, 0xB0, 0x00, BLOCK, 0x10」。您發送的緩衝區長度爲0F - 十進制爲15 - 但您必須讀取16字節,即0x10。 希望這有助於

1

在Mifare Classic 1K標籤有16個扇區,每個扇區包含4個塊,每個塊包含16個字節。

  1. 扇區0中包含塊(0,1,2,3)
  2. 扇區1包含塊(4,5,6,7)
  3. 扇區2包含塊(8,9,10,11 )
  4. 3區包含塊(12,13,14,15)....

閱讀之前或塊,您必須進行身份驗證使用密鑰A或該鍵B及其相應的部門寫部門。當驗證完成後,您可以讀取或寫入。使用此命令 您可以使用KEY A(60)

byte[] authenticationByte = new byte[10]; 

authenticationByte = new byte[] { (byte) 0xFF, (byte) 0x86, (byte) 0x00, 
(byte) 0x00, (byte) 0x05, (byte) 0x00,(byte) 0x00, (byte) 0x04, 
            (byte) 0x60,(byte) 0x00 }; 

當認證是更迭,那麼你會得到90 00.這就是成功的消息認證0扇區。否則,響應是63 00,這意味着認證失敗。當驗證完成後,您可以讀取塊(0,1,2,3),導致扇區0包含4個塊,那些塊(0,1,2,3)。 這裏你的問題是你正在驗證扇區1,但試圖從扇區0的塊中讀取數據。 欲瞭解更多詳情,你可以閱讀this Answer。 對不起,對不起英文