У меня есть считыватель NF C вместе с картой MIFARE Classi c 1K. У меня есть проект Visual C# winforms. Прямо сейчас я могу подключиться к ридеру, определить карту и получить ее UUID. Проблема, с которой я сталкиваюсь, заключается в написании и чтении данных. Я много искал по inte rnet, нашел какое-то решение, даже протестировал демонстрационный код, поставляемый с SDK ... ничего не работает.
Позвольте мне описать рабочий процесс и код, который я использую для записи, аутентификации блока, отправки APDU и чтения блока.
Ниже приведен код для записи данных в блок 5 .
String tmpStr = Text;
int indx;
if (authenticateBlock(Block))
{
ClearBuffers();
SendBuff[0] = 0xFF; // CLA
SendBuff[1] = 0xD6; // INS
SendBuff[2] = 0x00; // P1
SendBuff[3] = (byte)int.Parse(Block); // P2 : Starting Block No.
SendBuff[4] = (byte)int.Parse("16"); // P3 : Data length
SendBuff[5] = 0xFF;
SendBuff[6] = 0xFF;
SendBuff[7] = 0xFF;
SendBuff[8] = 0xFF;
SendBuff[9] = 0xFF;
SendBuff[10] = 0xFF;
for (indx = 0; indx <= (tmpStr).Length - 1; indx++)
{
SendBuff[indx + 5] = (byte)tmpStr[indx];
}
SendLen = SendBuff[4] + 5;
RecvLen = 0x02;
retCode = SendAPDUandDisplay(2);
if (retCode != Card.SCARD_S_SUCCESS)
{
MessageBox.Show("fail write");
}
else
{
MessageBox.Show("write success");
}
}
else
{
MessageBox.Show("FailAuthentication");
}
CloseCardConnection();
Функция SendAPDUandDisplay имеет следующий вид
private int SendAPDUandDisplay(int reqType)
{
int indx;
string tmpStr = "";
pioSendRequest.dwProtocol = Aprotocol;
pioSendRequest.cbPciLength = 8;
//Display Apdu In
for (indx = 0; indx <= SendLen - 1; indx++)
{
tmpStr = tmpStr + " " + string.Format("{0:X2}", SendBuff[indx]);
}
retCode = Card.SCardTransmit(hCard, ref pioSendRequest, ref SendBuff[0],
SendLen, ref pioSendRequest, ref RecvBuff[0], ref RecvLen);
if (retCode != Card.SCARD_S_SUCCESS)
{
return retCode;
}
else
{
try
{
tmpStr = "";
switch (reqType)
{
case 0:
for (indx = (RecvLen - 2); indx <= (RecvLen - 1); indx++)
{
tmpStr = tmpStr + " " + string.Format("{0:X2}", RecvBuff[indx]);
}
if ((tmpStr).Trim() != "90 00")
{
//MessageBox.Show("Return bytes are not acceptable.");
return -202;
}
break;
case 1:
for (indx = (RecvLen - 2); indx <= (RecvLen - 1); indx++)
{
tmpStr = tmpStr + string.Format("{0:X2}", RecvBuff[indx]);
}
if (tmpStr.Trim() != "90 00")
{
tmpStr = tmpStr + " " + string.Format("{0:X2}", RecvBuff[indx]);
}
else
{
tmpStr = "ATR : ";
for (indx = 0; indx <= (RecvLen - 3); indx++)
{
tmpStr = tmpStr + " " + string.Format("{0:X2}", RecvBuff[indx]);
}
}
break;
case 2:
for (indx = 0; indx <= (RecvLen - 1); indx++)
{
tmpStr = tmpStr + " " + string.Format("{0:X2}", RecvBuff[indx]);
}
break;
}
}
catch (IndexOutOfRangeException)
{
return -200;
}
}
return retCode;
}
Функция authenticateBlock имеет следующий вид
private bool authenticateBlock(String block)
{
ClearBuffers();
/*SendBuff[0] = 0xFF; // CLA
SendBuff[2] = 0x00; // P1: same for all source types
SendBuff[1] = 0x82; // INS: for stored key input
SendBuff[3] = 0x00; // P2 : Memory location; P2: for stored key input
SendBuff[4] = 0x05; // P3: for stored key input
SendBuff[5] = 0x01; // Byte 1: version number
SendBuff[6] = 0x00; // Byte 2
SendBuff[7] = (byte)int.Parse(block); // Byte 3: sectore no. for stored key input
SendBuff[8] = 0x60; // Byte 4 : Key A for stored key input
SendBuff[9] = (byte)int.Parse("1"); // Byte 5 : Session key for non-volatile memory
*/
SendBuff[0] = 0xD4;
SendBuff[1] = 0x4A;
SendBuff[2] = 0x01;
SendBuff[3] = 0x00;
SendBuff[4] = (byte) int.Parse(block);
SendBuff[5] = 0xFF;
SendBuff[6] = 0xFF;
SendBuff[7] = 0xFF;
SendBuff[8] = 0xFF;
SendBuff[9] = 0xFF;
SendBuff[10] = 0xFF;
/*SendLen = 0x0A;
RecvLen = 0x02;*/
SendLen = 4;
RecvLen = 255;
retCode = SendAPDUandDisplay(2);
if (retCode != Card.SCARD_S_SUCCESS)
{
//MessageBox.Show("FAIL Authentication!");
return false;
}
return true;
}
Одна странная вещь, на которую следует обратить внимание, это то, что независимо от того, какие значения я установил в sendBuff , эта функция всегда возвращает истинное значение, а код записи данных «Самый первый блок кода» возвращает запись success message
Но после выполнения кода записи данных, когда я читаю тот самый блок "5" в моем случае, там ничего не присутствует. Мой код чтения блока возвращает пустую строку, и когда я пытаюсь перепроверить, были ли записаны данные и не удалось прочитать мой неисправный код, я использую внешнее программное обеспечение, чтобы убедиться, что это добавленная стоимость или нет, это программное обеспечение также не делает показать данные, которые я написал и получил сообщение об успешной записи .
Хорошо, следующий код, который я использую для чтения блока 5.
public string readBlock(String Block)
{
string tmpStr = "";
int indx;
if (authenticateBlock(Block))
{
ClearBuffers();
/*
SendBuff[0] = 0xFF; // CLA
SendBuff[1] = 0xB0;// INS
SendBuff[2] = 0x00;// P1
SendBuff[3] = (byte)int.Parse(Block);// P2 : Block No.
SendBuff[4] = (byte)int.Parse("16");// Le
*/
SendBuff[0] = 0xD4;
SendBuff[1] = 0x40;
SendBuff[2] = 0x01;
SendBuff[3] = 0x30;
SendBuff[4] = byte.Parse(Block.ToString(), System.Globalization.NumberStyles.HexNumber);
SendBuff[5] = 0xFF;
SendBuff[6] = 0xFF;
SendBuff[7] = 0xFF;
SendBuff[8] = 0xFF;
SendBuff[9] = 0xFF;
SendBuff[10] = 0xFF;
//SendLen = 5;
//RecvLen = SendBuff[4] + 2;
SendLen = 5;
RecvLen = 255;
retCode = SendAPDUandDisplay(2);
if (retCode == -200)
{
return "outofrangeexception";
}
if (retCode == -202)
{
return "BytesNotAcceptable";
}
if (retCode != Card.SCARD_S_SUCCESS)
{
return "FailRead";
}
// Display data in text format
for (indx = 0; indx <= RecvLen - 1; indx++)
{
tmpStr = tmpStr + Convert.ToChar(RecvBuff[indx]);
}
return (tmpStr);
}
else
{
return "FailAuthentication";
}
}
Обратите внимание, что метод read block вызывается после проверки, подключен ли считыватель, если это так, тогда я вызываю метод readblock , и он возвращает пустую строку
Я пробовал несколько значений, как вы могли видеть в комментариях, но, похоже, ничего не помогло, прошло 3 долгих дня, и я все еще застрял здесь.
Может кто-нибудь, пожалуйста помогите мне понять, где я делаю это неправильно и какие значения я должен отправить для аутентификации блока?
Пожалуйста, сделайте мне одолжение, если кто-то узнает о проблеме в моем коде или захочет исправить значения, которые я задаю в sendBuff [] , тогда, пожалуйста, укажите их в C# кода, чтобы я мог использовать именно то решение, которое вы хотите, чтобы я реализовал
Любая искренняя помощь будет высоко оценена, заранее спасибо.