1
votes

All!

I'm trying to read data from mifare card 1k.
to get ID
I send: 0xFF 0xCA 0x00 0x00 0x00
Recive: 0x00 0x00 0x00 0x00 0x00 0x00 - ??? it's normal?

to load auth key to reader
I send: 0xFF 0x82 0x00 0x00 0x06 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
Recive: 90 00 - it's ok

to authenticate in block 01
I send: 0xFF 0x86 0x00 0x00 0x05 0x01 0x00 0x01 0x60 0x00
Recive: 90 00 - it's ok

to read data from block 01
I send: 0xFF 0xB0 0x00 0x01 0x0F
Recive: 63 00 - how a understand it's authentication error

I can't understand - why?

My code:

#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;
}

Can anyone explain why i got 63 00? Thanks.

2
Try authenticating with command 88 instead of 86, and then read the block. One possible authentication APDU can be: {FF, 88, 00, 01, 60, 00}).f.nasim

2 Answers

1
votes

Afair your read command has to be: "0xFF, 0xB0, 0x00, BLOCK, 0x10". You send buffer length 0F - which is decimal 15 - but you have to read 16 Byte, which is 0x10. Hope this helps

1
votes

In Mifare Classic 1K tags There are 16 Sectors and each Sectors contains 4 Blocks and each block contains 16 bytes.

  1. Sector 0 contains Block (0,1,2,3)
  2. Sector 1 contains Block (4,5,6,7)
  3. Sector 2 contains Block (8,9,10,11)
  4. Sector 3 contains Block (12,13,14,15)....

Before Reading or writing from a block You must have to Authenticate its corresponding Sector using Key A or Key B of that sector. When Authentication is complete then you can read or write. using this command you can authenticate sector 0 using 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 };

When Authentication is succes then you will get 90 00. That is Success message. Else response is 63 00 , that means authentication failed. When Authentication complete then you can read block (0,1,2,3) cause sector 0 contains 4 block and those are block (0,1,2,3). Here your problem is you are authenticating Sector 1 but trying to read data from Sector 0's blocks. For more details you can read this Answer. Sorry for bad English