Forum Replies Created
-
Re: Reply To: KeyA and KeyB and how to protect the contacless card from cloning?
15. February 2016 at 10:45 in reply to: KeyA and KeyB and how to protect the contacless card from cloning?Kind Thanks,
I read a lot about Mifare card. The driver interface that I have don’t explain very much. Even in demo code there isn’t any comment to make any sense.
In my app;
1) I can connect to the card
2) Load the Key (“FFFFFFFFFFFF” to save in terminal IC register somehow)
3) Authenticate
4) Read the block
5) Write to the block
I am having difficulty to understand the access bit rules. My understanding is this;
There are 2 access bit rules. 1 for the Data Block access bits and the other for Sector trailer access bit rules. Am I right?
I have a data that shown below.
My_Data1 = “2153”;
My_Data2 = “es56fg87p4f2”;
My_Data3 = “5852337644220001”;
My current default KeyA = “FFFFFFFFFFFF”
My current default KeyB = “FFFFFFFFFFFF”
If I use KeyA I can read and write my data into the Sector 1, Block 0, Block 1 and Block 2.
My main problem is I don’t know the access bits for data block or the sector trailer block.
First of all with my app I want to change all the KEY A, KEY B and the access bits. I need to use Key A for writing data into the card and I want to use Key B to read the data from card. Is it possible?
If so;
Example:
My new KeyA will be = “1665FE2AE945”
My new KeyB will be = “3321FB75A356”
1) How to change my Key A and Key B?
2) Do I need to change the sector trailer access bit?
3) How do I set new sector trailers bit?
4) How do I set new data block access bits for KEY_A for writing and KEY_B is for reading?
I know I have to use new sector trailer as;
" | access bits | general purpose byte | "
But is possible for you to give me an example regarding to use my above data, current key and new key?
So I can get in my brain. I am very confuse because of reading a lot and not having good documentation of API for my terminal.
Kind Regards,
+ 0 | - 0
Re: Reply To: Basic Tutorial for MIFARE Classic 1K using C#, C++ etc.
1. February 2016 at 8:00 in reply to: Basic Tutorial for MIFARE Classic 1K using C#, C++ etc.Hi mifaresdk,
Now I am getting somewhere. I will read the "proprietary class library" again. I will be post here the basic sample code later.
Your last post most helpful and clear to me.
Thank you very much.
Kind Regards,
+ 0 | - 0
Re: Reply To: Basic Tutorial for MIFARE Classic 1K using C#, C++ etc.
29. January 2016 at 11:47 in reply to: Basic Tutorial for MIFARE Classic 1K using C#, C++ etc.Hi mifaresdk,
I have no idea which library they used. I have a mifare.h and mifare.cpp in the sample project. But I couldn't find any mifare.so library file in the project.
Here is the header file.
#ifndef MIFARECLASSIC_H
#define MIFARECLASSIC_H
#include "AcsIncludes.h"
#define MAXIMUM_VALUE ************
enum MIFARE_KEY_TYPE {
MIFARE_KEY_TYPE_A = 0x60,
MIFARE_KEY_TYPE_B = 0x61
};
enum MIFARE_KEY_STORE {
MIFARE_KEY_STORE_0 = 0x00,
MIFARE_KEY_STORE_1 = 0x01
};
enum CARD_TYPE {
CARD_TYPE_UNKOWN = 0x00,
CARD_TYPE_MIFARE_1K= 0x01,
CARD_TYPE_MIFARE_4K = 0x02
};
class MifareClassic
{
public:
MifareClassic();
CARD_TYPE _eCardType;
void openReader();
void closeReader();
void connect();
void disconnect();
void loadKey(char *pKey, MIFARE_KEY_STORE eKeyStore);
void authenticate(MIFARE_KEY_TYPE eKeyType, uint8_t uBlockNumber, MIFARE_KEY_STORE eKeyStore);
void readBlock(uint8_t uBlockNumber, uint8_t uLength, char *pData);
void updateBlock(uint8_t uBlockNumber, uint8_t uLength, char *pData);
void storeValue(uint8_t uBlockNumber, uint64_t uValue);
void incrementValue(uint8_t uBlockNumber, uint64_t uValue);
void decrementValue(uint8_t uBlockNumber, uint64_t uValue);
void readValue(uint8_t uBlockNumber, uint64_t *pValue);
void restoreValue(uint8_t uSourceBlock, uint8_t uTargetBlock);
private:
};
#endif // MIFARECLASSIC_H
+ 0 | - 0
Re: Reply To: Basic Tutorial for MIFARE Classic 1K using C#, C++ etc.
28. January 2016 at 11:31 in reply to: Basic Tutorial for MIFARE Classic 1K using C#, C++ etc.Hi mifaresdk,
I use QT Creator opensource to develop my embedded Linux terminal app. I upload my app using Wi-Fi and FileZilla.
My terminal has physical RFID module that I can use this module to write and read Mifare 1K Classic contactless card.
There is also C++ mifare demo example that shows how to read from card and update info to the card. To get better understanding I need some basic information to start. Because there isn’t and documentation for the below example. I can read the code and make some sense out of it. But I am very confuse.
Example shows below code;
This is the main cpp.
DialogMifareCardProgramming::DialogMifareCardProgramming(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogMifareCardProgramming)
{
ui->setupUi(this);
cCard_.openReader();
}
There is a button on initializeForm that connects to the card. I guess……….
void DialogMifareCardProgramming::on_pushButtonConnect_clicked()
{
try
{
cCard_.connect();
initializeControls(true);
if (cCard_._eCardType == CARD_TYPE_MIFARE_1K)
ui->labelStatus->setText("Connected to Mifare 1K");
else if (cCard_._eCardType == CARD_TYPE_MIFARE_4K)
ui->labelStatus->setText("Connected to Mifare 4K");
else
ui->labelStatus->setText("Connected to unknown card");
}
catch(AcsException cExpection)
{
ui->labelStatus->setText(cExpection.sMessage);
initializeControls(false);
}
catch(...)
{
ui->labelStatus->setText("Connection failed");
initializeControls(false);
}
}
This is load key module. I don’t understand what is happening here.
void DialogMifareCardProgramming::on_pushButtonLoadKey_clicked()
{
MIFARE_KEY_STORE eKeyStore;
char aKey[6];
char aAsciiKey[12];
int iCounter = 0;
bool bNumeric = false;
try
{
ui->lineEditKeyStoreNumberInput->text().toInt(&bNumeric);
if (!bNumeric)
{
ui->labelStatus->setText("Invalid key store number");
return;
}
if (ui->lineEditKeyStoreNumberInput->text().toInt() == 0)
eKeyStore = MIFARE_KEY_STORE_0;
else if (ui->lineEditKeyStoreNumberInput->text().toInt() == 1)
eKeyStore = MIFARE_KEY_STORE_1;
else
{
ui->labelStatus->setText("Invalid key store number");
return;
}
if (ui->lineEditKey1->text().length() != 2 ||
ui->lineEditKey2->text().length() != 2 ||
ui->lineEditKey3->text().length() != 2 ||
ui->lineEditKey4->text().length() != 2 ||
ui->lineEditKey5->text().length() != 2 ||
ui->lineEditKey6->text().length() != 2)
{
ui->labelStatus->setText("Invalid key");
return;
}
memcpy(aAsciiKey, ui->lineEditKey1->text().toAscii().data(), 2);
memcpy(aAsciiKey + 2, ui->lineEditKey2->text().toAscii().data(), 2);
memcpy(aAsciiKey + 4, ui->lineEditKey3->text().toAscii().data(), 2);
memcpy(aAsciiKey + 6, ui->lineEditKey4->text().toAscii().data(), 2);
memcpy(aAsciiKey + 8, ui->lineEditKey5->text().toAscii().data(), 2);
memcpy(aAsciiKey + 10, ui->lineEditKey6->text().toAscii().data(), 2);
for (iCounter = 0; iCounter labelStatus->setText("Invalid key");
return;
}
}
cHelper_.getBytes(ui->lineEditKey1->text().toAscii().data(), aKey);
cHelper_.getBytes(ui->lineEditKey2->text().toAscii().data(), aKey + 1);
cHelper_.getBytes(ui->lineEditKey3->text().toAscii().data(), aKey + 2);
cHelper_.getBytes(ui->lineEditKey4->text().toAscii().data(), aKey + 3);
cHelper_.getBytes(ui->lineEditKey5->text().toAscii().data(), aKey + 4);
cHelper_.getBytes(ui->lineEditKey6->text().toAscii().data(), aKey + 5);
cCard_.loadKey(aKey, eKeyStore);
ui->labelStatus->setText("Load key succeeded");
}
catch(AcsException cException)
{
char *pMessage = new char[cException.sMessage.length() + 10];
sprintf(pMessage, "%02X %02X - %s", cException.aStatusWord[0], cException.aStatusWord[1], cException.sMessage.toUtf8().constData());
ui->labelStatus->setText(pMessage);
delete pMessage;
}
catch(...)
{
ui->labelStatus->setText("Load key failed");
}
}
And this is authentication module. Again I don’t understand what is happening in here….
void DialogMifareCardProgramming::on_pushButtonAuthenticate_clicked()
{
MIFARE_KEY_TYPE eKeyType;
MIFARE_KEY_STORE eKeyStore;
bool bNumeric = false;
try
{
if (ui->radioButtonKeyA->isChecked())
eKeyType = MIFARE_KEY_TYPE_A;
else if (ui->radioButtonKeyB->isChecked())
eKeyType = MIFARE_KEY_TYPE_B;
else
{
ui->labelStatus->setText("Please select key type");
return;
}
ui->lineEditKeyStoreNumber->text().toInt(&bNumeric);
if (!bNumeric)
{
ui->labelStatus->setText("Invalid key store number");
return;
}
if (ui->lineEditKeyStoreNumber->text().toInt() == 0)
eKeyStore = MIFARE_KEY_STORE_0;
else if (ui->lineEditKeyStoreNumber->text().toInt() == 1)
eKeyStore = MIFARE_KEY_STORE_1;
else
{
ui->labelStatus->setText("Invalid key store number");
return;
}
ui->lineEditBlockNumber->text().toInt(&bNumeric);
if (!bNumeric || ui->lineEditBlockNumber->text().toInt() labelStatus->setText("Invalid block number");
return;
}
if (cCard_._eCardType == CARD_TYPE_MIFARE_1K)
{
if (ui->lineEditBlockNumber->text().toInt() > 63)
{
ui->labelStatus->setText("Card does not have block " + ui->lineEditBlockNumber->text());
return;
}
}
else
{
if (ui->lineEditBlockNumber->text().toInt() > 255)
{
ui->labelStatus->setText("Card does not have block " + ui->lineEditBlockNumber->text());
return;
}
}
cCard_.authenticate(eKeyType, ui->lineEditBlockNumber->text().toInt(), eKeyStore);
ui->labelStatus->setText("Authentication succeeded");
}
catch(AcsException cException)
{
char *pMessage = new char[cException.sMessage.length() + 10];
sprintf(pMessage, "%02X %02X - %s", cException.aStatusWord[0], cException.aStatusWord[1], cException.sMessage.toUtf8().constData());
ui->labelStatus->setText(pMessage);
delete pMessage;
}
catch(...)
{
ui->labelStatus->setText("Authentication failed");
}
}
And this is update module. I guess like a write into the card.
void DialogMifareCardProgramming::on_pushButtonDataUpdate_clicked()
{
bool bNumeric = false;
try
{
ui->lineEditDataBlockNumber->text().toInt(&bNumeric);
if (!bNumeric || ui->lineEditDataBlockNumber->text().toInt() labelStatus->setText("Invalid block number");
return;
}
if (cCard_._eCardType == CARD_TYPE_MIFARE_1K)
{
if (ui->lineEditDataBlockNumber->text().toInt() > 63)
{
ui->labelStatus->setText("Card does not have block " + ui->lineEditDataBlockNumber->text());
return;
}
}
else
{
if (ui->lineEditDataBlockNumber->text().toInt() > 255)
{
ui->labelStatus->setText("Card does not have block " + ui->lineEditDataBlockNumber->text());
return;
}
}
ui->lineEditDataLength->text().toInt(&bNumeric);
if (!bNumeric || ui->lineEditDataLength->text().toInt() lineEditDataLength->text().toInt() % 16) != 0)
{
ui->labelStatus->setText("Invalid data length");
return;
}
if (ui->lineEditDataLength->text().toInt() != ui->textEditData->toPlainText().length())
{
ui->labelStatus->setText("Data length does not match");
return;
}
cCard_.updateBlock(ui->lineEditDataBlockNumber->text().toInt(), ui->lineEditDataLength->text().toInt(), ui->textEditData->toPlainText().toAscii().data());
ui->textEditData->setText("");
ui->labelStatus->setText("Update block succeeded");
}
catch(AcsException cException)
{
ui->textEditData->setText("");
char *pMessage = new char[cException.sMessage.length() + 10];
sprintf(pMessage, "%02X %02X - %s", cException.aStatusWord[0], cException.aStatusWord[1], cException.sMessage.toUtf8().constData());
ui->labelStatus->setText(pMessage);
delete pMessage;
}
catch(...)
{
ui->textEditData->setText("");
ui->labelStatus->setText("Update block failed");
}
}
Is it possible to tell me what is happening in these modules? I need to order say 1000 Mifare card for the pass through authentication services. So I have to write each card one by one. I don’t want to order card that has data and I have to update the data using above update module.
I will be happy if you can help me to understand the above code.
+ 0 | - 0
Thank you David for info.
Kind Regards
+ 0 | - 0
-
AuthorPosts