Mifare读取APDU命令已恢复63 00

时间:2013-08-05 13:46:44

标签: nfc mifare

所有!

我正在尝试从mifare卡1k读取数据 得到身份证 我发送:0xFF 0xCA 0x00 0x00 0x00
Recive:0x00 0x00 0x00 0x00 0x00 0x00 - ???这是正常的吗?

将auth键加载到阅读器
我发送:0xFF 0x82 0x00 0x00 0x06 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
Recive:90 00 - 没关系

在块01中进行身份验证 我发送:0xFF 0x86 0x00 0x00 0x05 0x01 0x00 0x01 0x60 0x00
Recive:90 00 - 没关系

从块01读取数据
我发送:0xFF 0xB0 0x00 0x01 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? 谢谢。

2 个答案:

答案 0 :(得分:1)

你的read命令必须是:“0xFF, 0xB0, 0x00, BLOCK, 0x10”。您发送缓冲区长度0F - 十进制15 - 但您必须读取16个字节,即0x10。 希望这有帮助

答案 1 :(得分:1)

在Mifare Classic 1K标签中有16个扇区,每个扇区包含4个块,每个块包含16个字节。

  1. 扇区0包含块(0,1,2,3)
  2. 扇区1包含块(4,5,6,7)
  3. 扇区2包含Block(8,9,10,11)
  4. 第3区包含Block(12,13,14,15)....
  5. 在从块读取或写入之前您必须使用该扇区的密钥A或密钥B对其相应的扇区进行身份验证。身份验证完成后,您可以读取或写入。 使用此命令,您可以使用KEY A(60)

    对扇区0进行身份验证
    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.这就是成功消息。否则响应是63 00,这意味着身份验证失败。验证完成后,您可以读取块(0,1,2,3),因为扇区0包含4个块,那些是块(0,1,2,3)。 在这里,您的问题是您正在验证扇区1,但尝试从扇区0的块中读取数据。 有关详细信息,请阅读this Answer。 对不起英文不好