2013-08-05 66 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。 对不起,对不起英文