1

全部!

我正在尝试从 mifare 卡 1k 读取数据。
获取
我发送的 ID:0xFF 0xCA 0x00 0x00 0x00
接收:0x00 0x00 0x00 0x00 0x00 0x00 - ??? 这是正常的?

将身份验证密钥加载到阅读器
我发送:0xFF 0x82 0x00 0x00 0x06 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
接收:90 00 - 没关系

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

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

4

2 回答 2

1

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

于 2013-10-30T06:50:46.657 回答
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) 验证扇区 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 的块中读取数据。有关更多详细信息,您可以阅读此答案。对不起英语不好

于 2015-01-31T16:16:20.743 回答