Обсуждаем цифровые устройства...
Ответить

Re: Ковыряем RFID Mifare и MFRC522

Вс окт 08, 2017 20:11:07

Так, в общем требуется собрать много информации прежде чем я опубликую работу с авторизацией.
Механизм не очень простой. Если у кого что есть ценное по этой теме сказать - пишите.

Так, начнем с теории и ссылок которые будут помогать в работе.
http://docs.cntd.ru/document/1200108880 читаем:
ИСО/МЭК 7816-4 - определяет организацию, защиту и команды для обмена информацией;
http://docs.cntd.ru/document/1200110393

-> 090A090001030100 [Calculate CRC]
-> A2A1 [GET CRC]
<- D0E3
-> 09 0A 090009D009E3010C0D80 [Send] - Команда авторизации 2kDES (улюч по умолчанию 8x00 вроде как)
-> 898989898989898989898989898989 [Read]
<- 0A 00 67 00 F3 A2

0A 00 - Команда верна. Код 00.
67 00 - Открываем вышеприведенный ГОСТ и смотрим что означает ответ.
Рисунок 1 - Структурная схема значений SW1-SW2
Ошибка контроля: 6700 = Неверно указанная длина (нет дальнейшего уточнения).
F3 A2 - CRC.

Что происходит.
Команда 0A = Авторизоваться через ключ 2kDES (он по умолчанию)
Ответ - неверно указанна длина. Вероятно длина ключа.

Пока еще не вьехал.
Есть example
--> 60
<-- af 04 01 01 00 02 18 05
--> af
<-- af 04 01 01 00 06 18 05
--> af
<-- 00 XX XX XX XX XX XX XX ZZ ZZ ZZ ZZ ZZ 05 06

60 - GetVersion.
AF - Листаем.
Так вот, у меня на данную команду карта не реагирует.

Конечно же ошибка с моей стороны, так как стандарт явно описывает формирование заголовка и тела команды. Есть строгие правила, но я пока не в теме как их выполнять.

Re: Ковыряем RFID Mifare и MFRC522

Пн окт 09, 2017 20:26:15

Так, ну что, начнем выяснять что делаю не так.
С простой командый - 60h - версия карты.
Пока что ничего не выходит. Команда ничего не отдает.
Знаю, что есть обертка по ISO 7816, но и в этой обертке я ничего от карты получить не могу.
Единственная команда на которую карта хоть что то отвечает - 0a - авторизация.
Но прежде чем делается авторизация вообще то должен быть выполнен селект.

Re: Ковыряем RFID Mifare и MFRC522

Вт окт 10, 2017 06:30:10

Так, ну что, начнем выяснять что делаю не так.

Конечно! Копирую все, что Вы накопали... :beer:

Re: Ковыряем RFID Mifare и MFRC522

Вт окт 10, 2017 19:45:27

Так, ну что, начнем выяснять что делаю не так.

Конечно! Копирую все, что Вы накопали... :beer:

:beer:

Добавлено after 9 minutes 19 seconds:
****************************************************
Приветствую.

Чисто случайно нашел кусок лога, где описывается получение версии. По идее нативный набор команд должен работать через обертку ISO 14443, но у меня не было времени снова открыть этот документ. Сегодня чуть позже покопаю еще.
Пока нет ясного представления как работать с картой (сказывается отсутствие закрытой документации). Но я держусь :)
В общем суть такая.
Отправляем карте 02 60
В ответ карта присылает первый блок данных:
-> B7 [Version]
<- 92
-> 01 0F 11 3D 2D 30 2C 00 2A 8D 2B 3E 14 83 26 70 15 40 [Init]
-> 09 52 01 0C 0D 87 [Send REQA]
-> 89 89 [Read]
<- 44 03
-> 09 93 09 20 01 0C 0D 80 [Anticol]
-> 89 89 89 89 89 [Read]
<- 88 04 5E 6F BD
-> 09 93 09 70 09 88 09 04 09 5E 09 6F 09 BD 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 0E 60
-> 09 93 09 70 09 88 09 04 09 5E 09 6F 09 BD 09 0E 09 60 01 0C 0D 80 [Select]
-> 89 89 89 [Read]
<- 24 D8 36
-> 09 95 09 20 01 0C 0D 80 [Anticol]
-> 89 89 89 89 89 [Read]
<- DA 49 34 80 27
-> 09 95 09 70 09 DA 09 49 09 34 09 80 09 27 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- A4 E1
-> 09 95 09 70 09 DA 09 49 09 34 09 80 09 27 09 A4 09 E1 01 0C 0D 80 [Select]
-> 89 89 89 [Read]
<- 20 FC 70
-> 0A 80 [Clear FIFO]
-> 09 E0 09 20 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 3B D6
-> 09 E0 09 20 09 3B 09 D6 01 0C 0D 80 [Send RATS]
-> 89 89 89 89 89 89 89 89 [Read]
<- 06 75 77 81 02 80 02 F0
-> 09 02 09 60 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 16 4E
-> 09 02 09 60 09 16 09 4E 01 0C 0D 80 [Send]
-> 89 89 89 89 89 89 89 89 89 89 89 89 89 89 [Read]
<- 02 AF 04 01 01 01 00 18 05 88 B9 DA DA DA

02 AF 04 - сообщает что это одна часть из 4 (ИМХО!)
Вообще давайте сразу определимся - я не учу работать с картами, я журналирую свои действия, не более того!
Продолжение следует.

Добавил в программу лог левел. Два. 1 - с оберткой над mfrc522, и 0 - без нее.
Смысл простой.
Вот лог без обертки.
-> B7 [Version]
<- 92
-> 01 0F 11 3D 2D 30 2C 00 2A 8D 2B 3E 14 83 26 70 15 40 [Init]
-> 52 01 0C 0D 87 [Send REQA]
<- 44 03
-> 93 20 01 0C 0D 80 [Anticol]
<- 88 04 5E 6F BD
-> 93 70 88 04 5E 6F BD 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 0E 60
-> 93 70 88 04 5E 6F BD 0E 60 01 0C 0D 80 [Select]
<- 24 D8 36
-> 95 20 01 0C 0D 80 [Anticol]
<- DA 49 34 80 27
-> 95 70 DA 49 34 80 27 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- A4 E1
-> 95 70 DA 49 34 80 27 A4 E1 01 0C 0D 80 [Select]
<- 20 FC 70
-> 0A 80 [Clear FIFO]
-> E0 20 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 3B D6
-> E0 20 3B D6 01 0C 0D 80 [Send RATS]
<- 06 75 77 81 02 80 02 F0
-> 02 60 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 16 4E
-> 02 60 16 4E 01 0C 0D 80 [Send]
<- 02 AF 04 01 01 01 00 18 05 88 B9

Сравните с логом сверху.
Разница проста:
Без обертки не фигурируют операции чтения 89 и записи байта данных 09.
Чистые куски лога требуются для общения в комьюнити MIFARE. Во всяком случае предполагается.

Если кто будет писать свой софт - сообщите. Хорошо бы на СИ все это дело завернуть.
Особенно, когда потребуются функции для побитовых операций XOR, калькуляции и работы с шифрованием.

Добавлено after 3 hours 36 minutes 25 seconds:
Эх, теперь все клеится к одному посту. Интересно, как долго движок форума будет клеить мессаги?
Ну, не суть. Продолжаем.
Сейчас будем пробовать листать ответ и поймем что он значит.
<- 02 AF 04 01 01 01 00 18 05 88 B9 crc
02 AF - AF означает что данные не переданы полностью и требуется листинг.
01 00 - тут должна быть версия (но не факт), вышло что версия карты 00 (такого не может быть).
18 - storage size is 18 (4096 bytes) - 4k - это факт, карта действительно 4k.
04 - я так понимаю что это количество байт в поле body ответа.
Поле body - 01 00 18 05
В общем без доки понятно что ничего не понятно, ничто не понято и интерпретировано из рук вон плохо!

Ковыряем тут. Много воды, но есть и много полезного - https://ridrix.wordpress.com/2009/09/19 ... n-example/

По поводу PPS Protocol Parameter Selection. Пока что есть надежда что все таки можно при помощи данной штуки переключить в ISO 7816
вряд-ли конечно.

Так, вот как листать многостраничные ответы.
Добавлено after 2 hours 52 minutes 22 seconds:
-> 02 60 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 16 4E
-> 02 60 16 4E 01 0C 0D 80 [Send]
<- 02 AF 04 01 01 01 00 18 05 88 B9 DA DA DA
-> 03 AF 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 35 69
-> 03 AF 35 69 01 0C 0D 80 [Send]
<- 03 AF 04 01 01 01 04 18 05 14 97 80 80 80
-> 02 AF 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- ED 70
-> 02 AF ED 70 01 0C 0D 80 [Send]
<- 02 00 04 5E 6F DA 49 34 80 BA 44 93 99 40 24 13 27 7D

Поясню
02 60 - запрос версии
02 AF - можно листать
03 AF - листаем далее
03 AF - есть еще страничка
02 AF - запрашивам еще одну страничку
02 00 - готово

Так, сейчас попробуем разобрать что это значит. Разбираем без нативной документации - не обессудьте.

02 AF 04 01 01 01 00 18 05 88 B9
01 00 - версия hardware 1.00
03 AF 04 01 01 01 04 18 05 14 97
01 04 - версия software - 1.04
02 00 04 5E 6F DA 49 34 80 BA 44 93 99 40 24 13 27
44 93 99 40 - серийный номер. Вообще он должен иметь пять байт, но не факт.
Если серийный номер пятизначный то тогда поменяли год и неделю местами в новых картах.
44 93 99 40 24 13 27 - 13 год 27 неделя.
Если не меняли ничего, то 24 13 - Карта произведена на 24-ю неделю 13 года. Но куда прилепить 27 ))
5E 6F DA 49 34 80 BA - UID


Так, еще кое что нашел на обертку:
https://www.nxp.com/docs/en/application ... pdf#page=9

Re: Ковыряем RFID Mifare и MFRC522

Чт окт 12, 2017 12:32:33

Авторизация.
Процедура:
1 - Выборали приложение.
Приложение на пустой карте только одно - 00 00 00
2 - Авторизовались.
Ключ 16 или 8 нулей, а то и 15. Будем посмотреть. Метод шифрования по умолчанию 3des

-> 02 5A 00 00 00 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 66 1F
-> 02 5A 00 00 00 66 1F 01 0C 0D 80 [Send]
<- 02 00 10 2D
-> 03 64 00 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 45 48
-> 03 64 00 45 48 01 0C 0D 80 [Send]
<- 03 00 00 70 4A

5A 00 00 00 - выбираем ApplicaionRoot (там хранится MasterKey)
64 00 - проверяем версию ключа
00 - 3DES или DES (пока не знаю).

Идем дальше.
-> 02 5A 00 00 00 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 66 1F
-> 02 5A 00 00 00 66 1F 01 0C 0D 80 [Select App]
<- 02 00 10 2D
-> 03 64 00 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- 45 48
-> 03 64 00 45 48 01 0C 0D 80 [Key Version]
<- 03 00 00 70 4A
-> 02 45 01 03 01 00 [Calculate CRC]
-> A2 A1 [GET CRC]
<- B9 38
-> 02 45 B9 38 01 0C 0D 80 [Key Settings]
<- 02 00 0F 01 37 FD

Команда 45 показывает конфигурацию ключа (права доступа).
0F 01
01 - количество ключей доступное для данного приложения. Мастер ключ - только один.
- [00001111] - права.

Изображение
Как всегда биты читаются справа налево! Прям классик какой то :)
http://img.radiokot.ru/files/125705/1egyk5hdvl.png

Re: Ковыряем RFID Mifare и MFRC522

Чт окт 19, 2017 12:42:40

Так, продолжаем. Сегодня о принципах авторизации.
Вспомним для начала что там у нас на данный момент получилось.
-> B7 [Version]
<- 92
-> 01 0F 11 3D 2D 30 2C 00 2A 8D 2B 3E 14 83 26 70 15 40 [Init]
-> 52 01 0C 0D 87 [Send REQA]
<- 44 03
-> 93 20 01 0C 0D 80 [Anticol]
<- 88 04 5E 6F BD
-> 93 70 88 04 5E 6F BD 0E 60 01 0C 0D 80 [Select]
<- 24 D8 36
-> 95 20 01 0C 0D 80 [Anticol]
<- DA 49 34 80 27
-> 95 70 DA 49 34 80 27 A4 E1 01 0C 0D 80 [Select]
<- 20 FC 70
-> 0A 80 [Clear FIFO]
-> E0 20 3B D6 01 0C 0D 80 [Send RATS]
<- 06 75 77 81 02 80 02 F0
-> 02 5A 00 00 00 66 1F 01 0C 0D 80 [Select App]
<- 02 00 10 2D
-> 03 64 00 45 48 01 0C 0D 80 [Key Version]
<- 03 00 00 70 4A
-> 02 45 B9 38 01 0C 0D 80 [Key Settings]
<- 02 00 0F 01 37 FD

Re: Ковыряем RFID Mifare и MFRC522

Вс окт 22, 2017 20:05:01

Короч, че то у меня странно MFRC522 работает с i2c шиной. Не хочет антенна заводиться на 3 вольта. От слова вообще. Еле еле карта работает. Сегодня буду разбираться в чем может быть проблема.
Я подозреваю отсутствие подтяжки SDA и SCL линии.
Еще как вариант - проблема с Atmega2560.
В общем попробую сдуть чип с референса и настроить его. Если и там подобные проблемы будут, то буду пробовать другого зверька, затем подтягивать SDA.

Подал питание с другого источника, 3 вольта, все отлично. Короч плохое питание. Идем дальше.
Так же что странно, не хочет нормально HEX принимать зверек. Вроде как принимает полнотелый HEX, а вот если 0x00 отправить, то уходят 4 бита скорее всего только начальные. Не факт, но похоже на то.

Так, выяснился еще какая то хрень с i2c. Адрес скачет не смотря на то, что я его задаю уровнями. Все ADDR ноги выставляем в 0 допустим. Включаем один раз - адрес 0x1c. Опять вырубаем врубаем - уже 0x28. И так далее. Берем другой источник питания - адрес вообще получаем другой 0x7f допустим. И он уже не меняется. То-есть от источника питания зависит адрес шины.

Я ее уже и подтягивал, и что я только с ней не делал. Результат один.

В общем плохо все с i2c. Как то не стабильно работает. Если адресация и дальше будет прыгать, то работать со зверьком не получится в нормальном режиме. UART, SPI - все работает идеально, проблемы только с I2C.

Еще покручу, и если надоест то буду использовать SPI. Обидно конечно, так как i2c позволяет работать с несколькими устройствам более гибко, и при этом используется на две жили меньше для подключения. 7 жил на SPI, и 5 - I2C.
Вообще можно было бы использовать UART, с ним вообще все идеально, и жил только 5, и антенна пашет отлично, но 115200 все же недостаточно. Между антенной и картой 418 кбит, 115 будет сводить эту полосу в четыре раза. ИМХО.

Re: Ковыряем RFID Mifare и MFRC522

Пн окт 23, 2017 22:07:53

Проблему решил проверкой ComIrqReg.
Еще оч важную штукуковину откопал.

Антенна GAIN - всегда после инита. В самом самом конце после прочих параметров.
Write(0X26,0X50);

У меня предпоследний параметр
Write(0X15,0X40);
затем настраиваю антенну.
Write(0X26,0X50);

Поставьте вот так
Write(0X26,0X50);
Write(0X15,0X40);

И получите нестабильную работу антенны на Desfire. ИМХО. Не изучено!

Произвел замер по току.
18 ма - ожидание.
32 ма - чтение: 0.5см.
22 ма - чтение: 5 см.

Напомню, что стандартные индукторы всего 7мА, нужна замена.

Re: Ковыряем RFID Mifare и MFRC522

Чт окт 26, 2017 22:03:33

Код для arduino,- авторизация пока не работает, к ней я в настоящий момент подхожу.
Работает поверх i2c.

Потребуется ардуинка с хорошим регулятором питания на 3.3в. У меня AMS1117-3.3.
На моей atmega2560 плата с плохим стабилизатором и в i2c ведет себя крайне нестабильно. Адрес пляшет, антенна работает плохо.
Однако SPI режим на той же плате уже работает хорошо.

rc522 переведенный в режим I2C. Или вот такая штука - https://ru.aliexpress.com/item/Compact- ... 8.3.07CeYf
Как перевести rc522 в i2c описано тут - https://www.google.de/url?sa=i&rct=j&q= ... 9546652098
У меня данная методика сработала только для UART. А вот i2c вроде как не завелся. Хотя могу сказать что метод там верный, и моя отладочная плата переключает режимы по тому же принципу.

Код:
/*
 * MadDogMayCry aka ~O8o
 * General Public Licence (GNU)
 * Education Desfire EV1 lib for MFRC522 over i2c
 * http://radiokot.ru/forum/viewtopic.php?p=3216806#p3216806
 */

#include <Wire.h>
#define address 0x28
byte crc[2];

void setup() {
  Wire.begin();
  Serial.begin(9600);
}

//Отправить байт
void Write(byte reg, byte value)
{
  Wire.beginTransmission(address);
  Wire.write(reg);
  Wire.write(value);
  Wire.endTransmission();
}

//Получить байт
unsigned char Read(unsigned char res){
  byte ucResult = 0;

  Wire.beginTransmission(address);
  Wire.write(res);
  Wire.endTransmission();
 
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 1);
  while (Wire.available()){
    ucResult = Wire.read();
  }
  Wire.endTransmission();
  return ucResult;
}

//Калькуляция CRC при помощи сопроцессора MFRC522
void GetCrc(byte *value, int *cnt){
  crc[0]=NULL;
  crc[1]=NULL;
  Write(0x0a,0x80);
  int i = 0;
  while (i<cnt){
    Write(0x09,value[i]);
    i++;
  }
  Write(0x01,0x03);
  crc[0]=Read(0xA2);
  crc[1]=Read(0xA1);
  Write(0x01,0x00);
}

//Аналог функции Serial.print() у которой 00,01,02... выводится как 0,1,2...
//Добавляет ведущий 0 к HEX значениям у которых он отсутсвует.
void Echo(byte value){
  if (value<0x10){
    Serial.print("0");
  }
  Serial.print(value,HEX);
  Serial.print(" ");
}

void loop() {
//Софтверный ресет
Write(0x01,0x0F);

//Конфигурируем mfrc522
Write(0x11,0x3D);
Write(0x2D,0x30);
Write(0x2C,0x00);
Write(0x2A,0x8D);
Write(0x2B,0x3E);
Write(0x14,0x83);
Write(0x15,0x40);

//Настройка усиления антенны 0x30, 0x40, 0x50, 0x60, 0x70 - максимум
Write(0x26,0x40);

//Отправляем REQA
Write(0x09,0x52);
Write(0x01,0x0C);
Write(0x0d,0x87);

//Карте нужно время на обмен данными
delay(1);

//Проверяем ATQA
//Desfire = 0x4403 и еще проверим есть ли в буффере 2 байта
if (Read(0x8a)==0x02 && Read(0x89)==0x44 && Read(0x89)==0x03){
  Serial.print("Карта Desfire / Desfire EV1");
  Serial.println();
  //Очищаем буффер
  Write(0x0a,0x80);

  //Каскадный уровень 1
  Write(0x09,0x93);
  Write(0x09,0x20);
  Write(0x01,0x0c);
  Write(0x0d,0x80);
 
  //1мс на передачу
  delay(1);

  //Читаем CT UID0 UID1 UID2 BCC (Первый SAK = 24)
  byte uid[] = {Read(0x89),Read(0x89),Read(0x89),Read(0x89),Read(0x89)};
 
  Serial.println("Каскадный уровень 1");
  Echo(uid[0]);Echo(uid[1]);Echo(uid[2]);Echo(uid[3]);Echo(uid[4]);
  Serial.println();

  //Расчитываем CRC сопроцессором mfrc522 - на выходе crc[0] и crc[1]
  byte crc_1[]={0x93,0x70,uid[0],uid[1],uid[2],uid[3],uid[4]};
  GetCrc(crc_1,7);
 
  //Очищаем буффер
  Write(0x0a,0x80);
 
  //Отправляем селект 1
  Write(0x09,0x93);
  Write(0x09,0x70);
  //Добавляем к строке первую часть UID
  Write(0x09,uid[0]);
  Write(0x09,uid[1]);
  Write(0x09,uid[2]);
  Write(0x09,uid[3]);
  Write(0x09,uid[4]);
  //Добавляем к строке CRC
  Write(0x09,crc[0]);
  Write(0x09,crc[1]);
 
  //Отправляем карте
  Write(0x01,0x0c);
  Write(0x0d,0x80);
 
  //1мс на передачу
  delay(1);

  //Читаем ответ
  Echo(Read(0x89));
  Echo(Read(0x89));
  Echo(Read(0x89));
  Serial.println();
 
  //Очищаем буффер на всякий случай
  Write(0x0a,0x80);

  Serial.println("Каскадный уровень 2");
  //Каскадный уровень 2
  Write(0x09,0x95);
  Write(0x09,0x20);
  Write(0x01,0x0c);
  Write(0x0d,0x80);
 
  //1мс на передачу
  delay(1);

  //Читаем UID3 UID4 UID5 UID6 BCC
  uid[5]=Read(0x89);
  uid[6]=Read(0x89);
  uid[7]=Read(0x89);
  uid[8]=Read(0x89);
  uid[9]=Read(0x89);

  Echo(uid[5]);Echo(uid[6]);Echo(uid[7]);Echo(uid[8]);Echo(uid[9]);
  Serial.println();
 
  //На всякий очищаем буффер
  Write(0x0a,0x80);

  //Расчитываем CRC сопроцессором mfrc522 - на выходе crc[0] и crc[1]
  byte crc_2[]={0x95,0x70,uid[5],uid[6],uid[7],uid[8],uid[9]};
  GetCrc(crc_2,7);
 
  //Отправляем селект 2
  Write(0x09,0x95);
  Write(0x09,0x70);
  //Добавляем к строке вторую часть UID
  Write(0x09,uid[5]);
  Write(0x09,uid[6]);
  Write(0x09,uid[7]);
  Write(0x09,uid[8]);
  Write(0x09,uid[9]);
  //Добавляем к строке CRC
  Write(0x09,crc[0]);
  Write(0x09,crc[1]);
  //Отправка
  Write(0x01,0x0c);
  Write(0x0d,0x80);
 
  delay(1);

  //Читаем ответ
  Echo(Read(0x89));
  Echo(Read(0x89));
  Echo(Read(0x89));
  Serial.println();
 
  //Выводим UID карты
  Serial.println("UID Карты");
  Echo(uid[1]);Echo(uid[2]);Echo(uid[3]);Echo(uid[5]);Echo(uid[6]);Echo(uid[7]);Echo(uid[8]);
  Serial.println();
 
  //На всякий очищаем буффер
  Write(0x0a,0x80);
 
  //Отправка RATS
  Write(0x09,0xE0);
  Write(0x09,0x20);
  //Нет смысла напрягать сопроцессор,- для 0xE0 0x20 CRC калькулировался заранее)
  Write(0x09,0x3b);
  Write(0x09,0xd6);
  //Отправка
  Write(0x01,0x0c);
  Write(0x0d,0x80);

  delay(1);
  Serial.println("ATS ответ");
  //Читаем ответ
  Echo(Read(0x89));
  Echo(Read(0x89));
  Echo(Read(0x89));
  Echo(Read(0x89));
  Echo(Read(0x89));
  Echo(Read(0x89));
  Echo(Read(0x89));
  Echo(Read(0x89));
  Serial.println();
  Serial.println();
}
delay(500);
}
Еще вам наверное сканер i2c устройств потребуется

Программа носит образовательный характер - понять принцип взаимодействия с Desfire EV1 так сказать.

Вот результат работы на данный момент:
Карта Desfire / Desfire EV1
Каскадный уровень 1
88 04 5E 6F BD
24 D8 36
Каскадный уровень 2
DA 49 34 80 27
20 FC 70
UID Карты
04 5E 6F DA 49 34 80
ATS ответ
06 75 77 81 02 80 02 F0

Почему начал работать с i2c, честно сказать тогда я еще не думал о том что i2c требует хороший источник питания. SPI по всей видимости менее требователен? ИМХО конечно. UART медлителен? Тоже ИМХО. В общем так уж вышло. Под SPI обязательно сделаю, там буквально две функции поправить и все.
UART кстати почему не учитывал. Там что бы переключить MFRC522 на нужный уровень, сначала надо на дефольной частоте подключиться (9600), потом произвести смену через регистр на требуемую скорость (максимальная вроде как 115200 ИМХО), и потом уже переключить управляющую программу на заданную скорость. Мне показалось как то много телодвижений для обвязки.

Добавляем после ATS

Теперь можно прочитать версию карты:
Карта Desfire / Desfire EV1
Каскадный уровень 1
88 04 5E 6F BD
24 D8 36
Каскадный уровень 2
DA 49 34 80 27
20 FC 70
UID
04 5E 6F DA 49 34 80
ATS
06 75 77 81 02 80 02 F0
Информация о карте
02 AF 04 01 01 01 00 18 05 88 B9
03 AF 04 01 01 01 04 18 05 14 97 02
02 00 04 5E 6F DA 49 34 80 BA 44 93 99 40 24 13 27 7D

Ну и в таком духе.
Еще раз напомню, что логической обвязки не должно быть. Чистая процедура!
Да, сильно много пространства занимает код, зато понятно конкретно по шагам что происходит.

Если будете переписывать функции read/write под SPI, пожалуйста сохраните процедурную ориентированность. Крайне важна примитивность в этой программе.

Плавно подхожу к авторизации.
Сейчас выполним селект рута (00 00 00) и запросим у него инфу о ключе.
Далее иду блоками. То-есть: кусочек добавляемого кода и его вывод.

Идем сюда viewtopic.php?p=3204527#p3204527 или листаем выше.
-> 02 5A 00 00 00 66 1F 01 0C 0D 80 [Select App]
<- 02 00 10 2D
-> 03 64 00 45 48 01 0C 0D 80 [Key Version]
<- 03 00 00 70 4A
-> 02 45 B9 38 01 0C 0D 80 [Key Settings]
<- 02 00 0F 01 37 FD

Я уже забыл как читать вывод, но суть там простая.
Выделили приложение 5a 00 00 00
Далее можно авторизоваться.
Или запросить версию ключа 64 00
Или настройки ключа 45
Вот сейчас попробуем добавить в нашу программу аналог, что бы получить те же самые данные. Будет хорошим примером.

По CRC - я не буду его запрашивать у сопроцессора, так как он уже расчитан. Эти данные не меняются в отличии от команд связанных с селектами.
CRC я расчитывал заблаговременно. Для 02 5a 00 00 00 = 66 1F затем следует команда отправки данных на карту 01 0C 0D 80
А вот и логическая ошибка :) на самом деле здесь есть динамическая переменная :) и в некоторых случаях потребуется расчет CRC динамически.

Не знаю на сколько целесообразно использовать сопроцессор mfrc522 для расчета crc16, но вроде как он это делает куда быстрее чем любая atmega или даже stm. У него там акселерация на аппаратном уровне, и никакой софт его по идее обогнать не способен. ИМХО! Вообще не тестил. Надо бы потестить потом.

Кстати, bit2 настройки ключа сообщает что без авторизации можно создавать и удалять аппликации. Может создадим чего для начала :)

Добавляем под информацию о карте
Код:
//Расчитываем CRC сопроцессором mfrc522 - на выходе crc[0] и crc[1]
  byte crc_3[]={0x03,0x5a,0x00,0x00,0x00};
  GetCrc(crc_3,5);
  //Выбираем приложение 00 00 00 (root)
  Write(0x09,0x03);Write(0x09,0x5a);Write(0x09,0x00);Write(0x09,0x00);Write(0x09,0x00);
  //CRC
   Write(0x09,crc[0]);
   Write(0x09,crc[1]);
  //Отправка
  Write(0x01,0x0c);Write(0x0d,0x80);
  delay(2);

  //Ответ
  Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));
  Serial.println();
  Serial.println();


Результат - 03 00 C8 34
03 00 - команда выполнена, с8 34 вроде как BCC или CRC
В чем же заключалась логическая ошибка я думаю вы можете разобраться сами взглянув на вывод.
Write(0x09,0x03);Write(0x09,0x5a);Write(0x09,0x00);Write(0x09,0x00);Write(0x09,0x00);

Все дело в нативном наборе команд.
Каждый запрос к карте требуется чередовать: 02, 03, 02.

Вот очередность:
Информация о карте
02 AF 04 01 01 01 00 18 05 88 B9
03 AF 04 01 01 01 04 18 05 14 97 02
02 00 04 5E 6F DA 49 34 80 BA 44 93 99 40 24 13 27 7D
03 00 C8 34

Re: Ковыряем RFID Mifare и MFRC522

Вс окт 29, 2017 00:29:45

Авторизация.
Суть авторизации Desfire сводится к следующему.
По дефолту на карте установлен DES KEY из 16 нулей.
Отправив запрос на авторизацию карте, нам возвращается RNDB последовательность байтов. зашифрованная этим самым ключем по умолчанию.
Расшифровываем, сдвигаем на 8 бит влево (битовое смещение на СИ).
Затем генерируем свой ключ, именуемый NXP как RNDA (RaNDomA).
Теперь надо взять RNDA + RNDB и зашифровать их таким же ключем, которым карта шифровала RNDB и отправить обратно карте.
Карта вышлет нам свой RNDA.
Его требуется расшифровать.
Затем сдвинуть 8 бит влево (ИМХО, не проверено).
Затем взять первую половину дешифрованного RNDA прибавить к ней первую половину дешифрованного RNDB, затем взять опять те же значения но в зеркальном виде RNDB + RNDA а так же помнить, что DES игнорирует каждый 8-ой бит байта. Он должен быть в позиции 0.
То-есть комбинация первых четырех байт (4)RNDA + (4)RNDB + (4)RNDA + (4)RNDB =сессионный ключ IV.
Что с ним делать я пока не знаю, но для начала попробую получить именно его.

В общем то ничего сложного по сути нет, будем поглядеть как говорится.

Re: Ковыряем RFID Mifare и MFRC522

Вт окт 31, 2017 01:11:55

Внимание. Все что я описывал о шагах авторизации Desfire до данного момента не является TRUE. Принцип верный, но детали не описаны.

Авторизация чере des/3des = 1a ключ 00 (root)
-> 1a 00
<- 5D 99 4C E0 85 F2 40 89

5D 99 4C E0 85 F2 40 89 = RndB Карты.
Не торопимся его декодировать.

Теперь генерируется свой RndA
84 9B 36 C5 F8 BF 4A 09

Далее требуется так называемое сложение по модулю (XOR)
0 + 0 = 0
1 + 0 = 1
0 + 1 = 1
1 + 1 = 0

5D 99 4C E0 85 F2 40 89 ^ 84 9B 36 C5 F8 BF 4A 09 = D9 02 7A 25 7D 4D 0A 80
Шифруем D9 02 7A 25 7D 4D 0A 80
Результат 21 D0 AD 5F 2F D9 74 54
Ура. По шаблону проверил, это первая часть ответа. Дальше будет интересней :)

Теперь берем зашифрованный RndB - 5D 99 4C E0 85 F2 40 89 и дешифруем (des/3des) (0x00 00 00 00 00 00 00 00 ~ HEX)
Результат RndB_dec - 4F D1 B7 59 42 A8 B8 E1 делаем смещение << на 8 бит. Результат = D1 B7 59 42 A8 B8 E1 4F
Теперь берем 21 d0 ad 5f 2f d9 74 54 ^ d1 b7 59 42 a8 b8 e1 4f и производим сложение по модулю (XOR)
Результат = f0 67 f4 1d 87 61 95 1b
Шифруем = A746CC80567F1B1C
А вот и вторая половина RNDAB_enc = 21D0AD5F2FD97454 A746CC80567F1B1C
Отправляем карте на что получаем RNDA_enc.

Ответ - 91 3C 6D ED 84 22 1C 41 ^ A746CC80567F1B1C = 9b 36 c5 f8 bf 4a 09 84 << 8 = 36 c5 f8 bf 4a 09 84 9b
If rnda == rnda_enc_dec (36 c5 f8 bf 4a 09 84 9b == 36 c5 f8 bf 4a 09 84 9b) значит мы авторизовались ;)

Идем дальше. Вот простая схема, показывающая смысл происходящего:
rndb 5D 99 4C E0 85 F2 40 89
rnda 84 9B 36 C5 F8 BF 4A 09
XOR = D9 02 7A 25 7D 4D 0A 80
XOR_enc 21 D0 AD 5F 2F D9 74 54
rndb_dec_rot D1 B7 59 42 A8 B8 E1 4F
XOR = f0 67 f4 1d 87 61 95 1b
XOR_enc = A7 46 CC 80 56 7F 1B 1C

Я тут смотрел в сети народ активно обсуждал разные алгоритмы.
Кто то предлагал 3DES(randA) + 3DES(randB' XOR 3DES(randA)) но у меня подобная форумала вообще не работает. Есть вероятность что я ее понял не правильно.
Кто то вообще предложил TDES_CBC(randA | randB), но второй вариант вообще не понятно как вычислять без XOR и смещения, так как карта сама по себе смещает 8 бит вправо любую последовательность возвращаемую процессору.

Моя формула выглядит так: part1(Des(rndB ^ rndA)) + des(rndb_dec_rot ^ part1);
Или 3desCBC(IV=5D994CE085F24089(84 9B 36 C5 F8 BF 4A 09)) = 21D0AD5F2FD97454
Надо понимать, что 3des = des_enc + des_dec + des_enc. То-есть второй вариант уже потратил три подхода, но создал только первую часть, тогда как
первый вариант создал сразу две части за три прохода.
Какой из данных вариантов более оптимальный по производительности надо будет выяснить.

Схема рабочая, требует 2 прохода шифрования (DES) и один дешифровки (DES). То-есть три прохода des = 1 проход 3des. То-ли у меня проблема с логикой, то-ли народ производит в три раза больше проходов чем требуется (см.выше).
Впрочем, это по сути тот же 3des с CBC. То-есть по сути, в теории, предложение использовать TDES_CBC(randA | randB) похоже на TRUE, но я как не пытался раскорячиться,- ну никак. Буду еще ковырять эту тему.
В общем пока не понимаю на 100% как эта штука функционирует.

Народ который разобрался в теме и выложил логи, которые не дают полного представления о механике.
Вот пример одного из них:

* RndB_enc: 5D 99 4C E0 85 F2 40 89
* RndB: 4F D1 B7 59 42 A8 B8 E1
* RndB_rot: D1 B7 59 42 A8 B8 E1 4F
* RndA: 84 9B 36 C5 F8 BF 4A 09
* RndAB: 84 9B 36 C5 F8 BF 4A 09 D1 B7 59 42 A8 B8 E1 4F
* RndAB_enc: 21 D0 AD 5F 2F D9 74 54 A7 46 CC 80 56 7F 1B 1C

Результат: ED7DDE10C75977DC753BA677F37133BD
Должно быть: 21 D0 AD 5F 2F D9 74 54 A7 46 CC 80 56 7F 1B 1C

Ладно, это дело такое.
Значит после отправки вот этой строки карте 21 D0 AD 5F 2F D9 74 54 A7 46 CC 80 56 7F 1B 1C
карта должна ответить статусом 00 и выслать нам наш rnda. В принципе, если статус 00, то это уже означает успех и авторизация является свершенной, но это все мое субьективное ИМХО.

После успешной авторизации, у нас на руках появился сесионный ключ. В чем его суть я пока не в теме, но вроде как народ при его помощи вычисляет некий CMAC. Я пока не читал что это, но по ходу эта штука нам помогает кодировать/декодировать ответы, и она каждый раз меняется после обмена меняется особым образом. ИМХО.

Далее теория, которая возможно не имеет ничего общего с реальность.
Session Key (IV) мы можем получить взяв первые четыре байта RNDA + первые четыре байта RNDB + повторим еще раз.
84 9B 36 C5 4F D1 B7 59 84 9B 36 C5 4F D1 B7 59
Но все не так просто, DES игнорирует каждый 0 бит байта, а значит потребуется операция, которая на C/C++ выглядит следующим образом

байт&=~(1<<0);

Пример:
84 9B 36 C5 4F D1 B7 59 84 9B 36 C5 4F D1 B7 59
84 9A 36 C4 4E D0 B6 58 84 9A 36 C4 4E D0 B6 58

Что бы понимать о чем речь.
Возьмем первые два байта:
84 9B - 10000100 10011011
84 9A - 10000100 10011010

84 9A 36 C4 4E D0 B6 58 84 9A 36 C4 4E D0 B6 58

Вероятно это и есть IV key.
Message authentication code = MAC (4 byte) 84 9A 36 C4 4E D0 B6 58
CMAC (зашифрованный MAC).
Вообще MAC используется для коммуникации через AES. Но не уверен.
Все это ИМХО, так как этот вопрос я сейчас и разбираю.

http://nvlpubs.nist.gov/nistpubs/Legacy ... 00-38b.pdf

Re: Ковыряем RFID Mifare и MFRC522

Чт ноя 02, 2017 02:27:41

Так, что на данный момент стало известно.
1 - после авторизации обмен данными с картой так же шифруется (схема у NXP как водится своя) :) не могут эти ребята без танцев с бубном.
2 - Требуется формировать блоки по 8 байт, если пакет больше 8 байт, то устанавливается padding. Допустим пакет имеет длину 12 байт, значит вместе с паддингом получится 16 байт, то-есть кратно 8-ми.
3 - Эти пакеты требуется шифровать/дешифровать методом от NXP :)
http://read.pudn.com/downloads134/ebook ... df#page=29

Re: Ковыряем RFID Mifare и MFRC522

Пн ноя 06, 2017 21:38:06

Приветствую. Долго ничего не выкладывал. Изучал дополнительную информацию.
Функция расчета CRC16 для MIFARE (полином 6363) на ардуинку.
Если оптимизируете буду очень рад.
Код:
byte crc16[2];

void setup() {
 Serial.begin(9600);
}

unsigned short GetCrc(unsigned char *data, unsigned int len){
  unsigned int i;
  unsigned short crc= 0x6363;
  for(i= 0; i < len ; ++i){
    unsigned short n, v, tcrc = 0;
    v = (crc ^ data[i]) & 0xff;
    for (n = 0; n < 8; n++){
      tcrc = ( (tcrc ^ v) & 1 ) ? ( tcrc >> 1 ) ^ 0x8408 : tcrc >> 1;
      v >>= 1;
    }
    crc = ((crc >> 8) ^ tcrc) & 0xffff;
  }
  crc16[0] = crc & 0xff;
  crc16[1] = (crc >> 8) & 0xff;
}
void loop() {
  byte data[] = {0xe0,0x20};
  GetCrc(data,2);
  Serial.print(crc16[0],HEX);
  Serial.print(" ");
  Serial.println(crc16[1],HEX);
  delay(5000);
}
Еще один
Код:
uint16_t CalcCrc16(const byte* u8_Data, int s32_Length){
    uint16_t u16_Crc = 0x6363;
    for (int i=0; i<s32_Length; i++){
        byte ch = u8_Data[i];
        ch = ch ^ (byte)u16_Crc;
        ch = ch ^ (ch << 4);
        u16_Crc = (u16_Crc >> 8) ^ ((uint16_t)ch << 8) ^ ((uint16_t)ch << 3) ^ ((uint16_t)ch >> 4);
    }
    crc16[0] = u16_Crc & 0xff;
    crc16[1] = (u16_Crc >> 8) & 0xff;
    //return u16_Crc;
}
CRC32
Код:
uint32_t CalcCrc32(const byte* u8_Data, int s32_Length, uint32_t u32_Crc = 0xFFFFFFFF){
    for (int i=0; i<s32_Length; i++){
        u32_Crc ^= u8_Data[i];
        for (int b=0; b<8; b++){
            bool b_Bit = (u32_Crc & 0x01) > 0;
            u32_Crc >>= 1;
            if (b_Bit){
              u32_Crc ^= 0xEDB88320;
            }
        }
    }
    crc32[3] = u32_Crc & 0xff;
    crc32[2] = (u32_Crc >> 8) & 0xff;
    crc32[1] = (u32_Crc >> 16) & 0xff;
    crc32[0] = (u32_Crc >> 24) & 0xff;
    return u32_Crc;
}

Re: Ковыряем RFID Mifare и MFRC522

Ср ноя 08, 2017 04:02:06

Так как MFRC522 возвращает количество байт в буффере HEX значением, не плохо было бы
конвертировать это значение в DEC.
Я не уверен что POW быстр, но других вариантов я пока не нашел.
Код:
int GetBufferSize(){
      return Read(0x8a);
}

Чё то я ступил. Оказывается возвращает нормальное значение. Странно. Я был убежден в том что возвращалось HEX значение. Инженеры NXP - зачёт.

Re: Ковыряем RFID Mifare и MFRC522

Чт ноя 16, 2017 16:04:21

Сегодня великий день :) я авторизовал карту ключом по умолчанию.
Ниже лог.
<- 44 03
-> 93 20
<- 88 04 5E 6F BD
-> 93 70 88 04 5E 6F BD 0E 60
<- 24 D8 36
-> 95 20
<- DA 49 34 80 27
-> 95 70 DA 49 34 80 27 A4 E1
<- 20 FC 70
-> E0 20 3B D6
<- 06 75 77 81 02 80 02 F0
-> 02 5A 00 00 00 66 1F
<- 02 00 10 2D
-> 03 1A 00 91 22
<- 03 AF FB E5 B2 66 B9 25 28 90 95 22
RND_B
<- FB E5 B2 66 B9 25 28 90
RND_A
<- AA BB CC AA BB CC AA BB
RND_B_DEC
<- 16 8C 6D 50 55 A9 E4 3B
RND_B_ROT
<- 8C 6D 50 55 A9 E4 3B 16
RND_B_ROT_ENC
<- 63 05 83 3D 72 22 55 33
-> 02 AF 8B A6 7A 9C 90 4F 1A C4 63 05 83 3D 72 22 55 33 5A 3D
<- 02 00 52 87 25 00 68 BC 69 69 E7 EC
RND_B IV
<- 63 05 83 3D 72 22 55 33
RND_A_ENC
<- 52 87 25 00 68 BC 69 69
RND_A_DEC
<- BB CC AA BB CC AA BB AA
Механика незамысловатая.
5A 00 00 00 - выбираем root приложение 00 00 00
Карта отвечает статусом 00
Отправляем команду авторизации DES 1A через мастер ключ 00.
Карта генерирует рандомный 8 байтовый ключ (rnd_b) FB E5 B2 66 B9 25 28 90
Теперь надо сгенерировать свой рандомный 8 байтовый ключ (rnd_a).
Затем требуется методом DES/CBC зашифровать свой rnd_a используя в качестве IV вектора ранее полученный rnd_b.
Теперь необходимо расшифровать rnd_b с начальным IV вектором 00 00 00 00 00 00 00 00 (8 HEX байт).
Теперь надо взять расшифрованный rnd_b и произвести смещение влево на один байт (<< 8 бит), другими словами первый байт переставить в конец.
Например: 01 02 03 04 ( << 8 ) = 02 03 04 01.
Теперь надо опять зашифровать rnd_b но в качестве IV вектора использовать наш зашифрованный rnd_a.
Таким образом у нас на руках зашифрованный rnd_a, зашифрованный rnd_b которые мы обьединяем в один 16 байтовый массив.
Теперь необходимо отправить эти данные карте:
-> 02 AF 8B A6 7A 9C 90 4F 1A C4 63 05 83 3D 72 22 55 33 5A 3D
И если все правильно, получить ответ:
<- 02 00 52 87 25 00 68 BC 69 69 E7 EC
Карта возвращает статус 00 если авторизация выполнена успешно, и высылает зашифрованный rnd_a со смещеннием.
RND_A_DEC
<- BB CC AA BB CC AA BB AA
Все просто.
На этапе формирования ключа из не шифрованных rnd_a и rnd_b так же формируется Session key.
В случае с DES, он генерируется следующим образом.
1 половина rnd_a + 1 половина rnd_b
+
1 половина rnd_a + 1 половина rnd_b
Но это только в случае с DES.
3DES/AES иначе.
Session Key нужен для генерации зашифрованных блоков сообщений, так как все данные между картой и устройством зашифрованы.

Странное наблюдение. Если попытаться авторизоваться через команду 0a, то RND_A возвращается некорректный. Надо будет разобраться почему, но первое что приходит в голову - карта EV1 отличается от прошлых версий DESFIRE на программном уровне ИМХО.

Чуть более удобный лог.
<- 44 03
-> 93 20
<- 88 04 5E 6F BD
-> 93 70 88 04 5E 6F BD 0E 60
<- 24 D8 36
-> 95 20
<- DA 49 34 80 27
-> 95 70 DA 49 34 80 27 A4 E1
<- 20 FC 70
-> E0 20 3B D6
<- 06 75 77 81 02 80 02 F0
-> 02 5A 00 00 00 66 1F
<- 02 00 10 2D
-> 03 1A 00 91 22
<- 03 AF B5 00 EA 45 0E 90 0D 97 40 15
RND_B_RECIVED <- B5 00 EA 45 0E 90 0D 97
RND_A <- AA BB CC AA BB CC AA BB
RND_A_ENC <- F6 3D 7B 70 0D 17 C2 8F
RND_B_DEC <- 36 6D B6 12 3A 17 F7 DA
RND_B_ROT <- 6D B6 12 3A 17 F7 DA 36
RND_B_ROT_ENC <- C6 2D F4 1A 9B A2 8C 46
-> 02 AF F6 3D 7B 70 0D 17 C2 8F C6 2D F4 1A 9B A2 8C 46 77 F3
<- 02 00 8D 6C DF 4E E6 7D F5 70 C4 5B
RND_A_RECIVED <- 8D 6C DF 4E E6 7D F5 70
RND_B IV <- C6 2D F4 1A 9B A2 8C 46
RND_A_RECIVED_DEC <- BB CC AA BB CC AA BB AA
SessionKey <- AA BB CC AA 36 6D B6 12 AA BB CC AA 36 6D B6 12

Session key нужен для шифрования CMAC. CMAC = шифрованное при помощи Session Key сообщение.
Оно вроде как блоками по 8 байт для DES и 16 байт для 3des/AES.
Вообще я представляю себе это так.
Допустим я хочу отправить команду 60 карте, выходит я создаю блок 8 байт (des) 60 00 00 00 00 00 00 00 затем шифрую его, создаю CRC и отправляю карте. Пока еще не пробовал но в теории все должно быть так.
Есть вероятность что сначала нужно расчитать CRC, затем только зашифровать, и потом отправить. А возможно перед отправкой расчитать CRC еще раз. В общем пока что тёмный лес 8)

Re: Ковыряем RFID Mifare и MFRC522

Сб ноя 18, 2017 18:25:16

А вот и не так. Дело в том что у карты существуют так называемые уровни.
Уровень PICC, app, file.
Команда версии работает на уровне PICC, ее шифровать не обязательно ИМХО.
Выбор приложения является уровнем APP, и там уже половина команд шифрованная и половина - нет.
Например при смене пароля или KEY_SETTINGS на уровне APP то сама команда не шифруется, а вот данные ключа или новых ключевых настроек надо шифровать.
На уровне file настройка уровня настраивается.
Без шифрования.
Защита MAC.
Полностью зашифрованное.
Это сделано для защиты данных. Между картой и устройством может быть подложен перехватчик, и он может знать какие приложения есть на карте, так как эти данные можно получить на уровне PICC, но никак не что то иное. Все это мое ИМХО основанное на доступной в сети информации которая возможно уже устарела.
На пример у карт EV1 устройство может шифровать данные и передавать карте, в то время как старые версии карт умели выполнять только операцию шифрования, и перед отправкой на карту надо было наоборот производить операцию ДЕшифровки. Вот так.

Re: Ковыряем RFID Mifare и MFRC522

Вс ноя 19, 2017 17:34:56

Сегодня попробую при помощи SessionKey поменять ключ в приложении.
Напомню, что DES игнорирует 0 бит каждого байта в массиве.
Перед использованием SessionKey требуется обработать массив функцией.
void ArrForDes(byte *arr,int cnt){
for(int i=0;i<8;i++){
arr[i]&=~(1<<0);
}
}

byte test[]={0x84, 0x9B, 0x36, 0xC5, 0x4F, 0xD1, 0xB7, 0x59};
ArrForDes(test,8);
<- 84 9A 36 C4 4E D0 B6 58

Этого можно не делать, но вроде как данные зашифрованные при помощи ключа необработанного подобным образом - можно взломать.
Атака вроде как связана с битом состояния который использует DES алгоритм. ИМХО.

Теперь о ключах
-> 02 45 B9 38
<- 02 00 0F 01 D5 96 56 EF B5 DF AC C6 6C B7
45 - получить настройки ключа выбранного приложения.
Ранее я создал приложение (об этом позже) с определенными параметрами ключа.
0F - это настройки доступа о них есть информация выше, но я еще раз озвучу ниже.
01 - количество ключей, но не все так просто. Дело в том что у Desfire есть разные типы ключей.
Есть DES/3DES/AES. Так вот 01 это байт, который несет в себе и количество доступных ключей, и тип ключей одновременно.
Я сначала не сразу это осознал. Не мог понять, что же тут не так. :)
Каждому приложению доступно 14 ключей.

01:
0 - версия ключа DES.
1 - количество ключей.
Но ведь нет такого HEX значения 012 на-пример, это уже два HEX значения.

Так каким образом производитель уместил 14 ключей да еще и их тип в одно HEX значение? :)
Да все просто.
0~[123456789ABCDE]~F

Вот вам и 14 ключей во второй части HEX значения, а тип - в первом.
HEX = [тип][количество]

Типы:
0 = des/3des
4 = 3k3des
8 = aes

Результат
8A = AES/10 ключей.
01 = DES/1 ключ
4E = 3k3des/14 ключей.

Все гениальное - просто.
Что касается типа DES/3DES - у меня пока открыт вопрос относительно одного момента, но я о нем умолчу и оставлю на потом.

Что бы не портить ключ по умолчанию в рут приложении (мало ли доступ потеряю по ошибке) создам свое приложение на карте.
Попробуем создать без авторизации.
-> 02 CA AA BB CC 0B 01 1C C3
<- 02 00 10 2D
Вот пример созданного приложения.
AA BB CC с правами доступа 0b, и одним DES/3des(?) ключом.

Теперь отправим команду списка приложений на карте
-> 03 6A 94 F8
<- 03 00 AA BB CC 91 B3
AA BB CC - есть такое.

Всем новым приложениям по умолчанию присваивается ключ заполненный нулями.
Я так понял, что если допустим указать ключевую версию 8 (AES), то создастся ключ заполненный нулями, и алгоритм проверки будет использован AES (ИМХО). Можно очень легко проверить.

Выбираем приложение
-> 02 5A AA BB CC 6D B1
<- 02 00 10 2D

Проверяем установки ключа
-> 03 45 61 21
<- 03 00 0B 01 EC 86
Сравниваем с нашими
0B - права доступа
01 - DES/1 ключ

Ок, пробую авторизоваться. В первую очередь это даст понять, каким ключом заполняется тип - 0.
-> 02 5A AA BB CC 6D B1
<- 02 00 10 2D
-> 03 1A 00 91 22
<- 03 AF 82 84 42 2B F4 FC 46 05 02 F2
RND_B_RECIVED <- 82 84 42 2B F4 FC 46 05
RND_A <- AA BB CC DD AA BB CC DD
RND_A_ENC <- 11 A7 C6 E9 75 51 B8 C9
RND_B_DEC <- 3A 40 75 57 25 5E 94 39
RND_B_ROT <- 40 75 57 25 5E 94 39 3A
RND_B_ROT_ENC <- B9 13 6C 0F CD 9A A0 7B
-> 02 AF 11 A7 C6 E9 75 51 B8 C9 B9 13 6C 0F CD 9A A0 7B 5E E3
<- 02 00 61 45 04 AB 33 B1 FF 12 D9 BB
RND_A_RECIVED <- 61 45 04 AB 33 B1 FF 12
RND_B_ROT_ENC <- B9 13 6C 0F CD 9A A0 7B
RND_A_RECIVED_DEC <- BB CC DD AA BB CC DD AA
SessionKey @ ArrForDes <- AA BA CC DC 3A 40 74 56 AA BA CC DC 3A 40 74 56
-> 03 45 61 21
<- 03 00 0B 01 B2 F1 0D 0E DC DF 47 48 11 E3

Тип - 0, ключ заполнен нулями (об этом свидетельствует RND_A_RECIVED_DEC, полученный в результате шифрования 8-ю нулями/DES), а алгоритм шифрования DES/3DES.
Дело в том, что скорее всего карта использует алгоритм 3DES, если видит, что вторая часть ключа, не является копией первой половины. Тогда она
автоматически начинает шифровать ключ тремя подходами DES c CBC соединением блоков через вектор, что в свою очередь можно считать алгоритмом 3des.
На сколько я помню, 3des делает следующее.
Один проход - шифрование.
Второй - дешифрование с IV вектором результата первого прохода.
Третий - шифрование с IV вектором результата второго прохода.
Пока это ИМХО, как бы выводы основанные на поверхностных изысканиях.

Позже я это обязательно проверю.

Ключевая версия указывает, что это мой ключ, а не мастер ключ 00 в рут приложении 00 00 00, так как у него параметры доступа по умолчанию
-> 03 45 61 21
<- 03 00 0F 01 AA A6 D7 C2 10 6B 6D 99 9D 9C
0F [00001111]- можете глянуть выше табличку, я ее приводил для наглядности.
А у моего приложения 0B [00001011].
3 бит установлен в 0, что позволяет удалять это приложение без авторизации в самом приложении.

Теперь я точно знаю, что буду менять именно мой ключ а не мастер ключ карты.
Мне так же известно, что ключ заполнен нулями, а алгоритм шифрования используется - DES.

Re: Ковыряем RFID Mifare и MFRC522

Пт ноя 24, 2017 17:20:05

Смена DES ключа по умолчанию.
<- 44 03
-> 93 20
<- 88 04 5E 6F BD
-> 93 70 88 04 5E 6F BD 0E 60
<- 24 D8 36
-> 95 20
<- DA 49 34 80 27
-> 95 70 DA 49 34 80 27 A4 E1
<- 20 FC 70
-> E0 20 3B D6
<- 06 75 77 81 02 80 02 F0
-> 02 5A AA BB CC 6D B1
<- 02 00 10 2D
-> 03 0A 00 00 B7
<- 03 AF BF 79 A5 EA 0D 8C 6D E5 BD EC
RND_B_RECIVED <- BF 79 A5 EA 0D 8C 6D E5
RND_A <- AA BB CC DD AA BB CC DD
RND_A_DEC <- 8D 1C D7 3F AD 69 B2 77
RND_B_DEC <- 40 3B 8B 60 71 EB 53 46
RND_B_ROT <- 3B 8B 60 71 EB 53 46 40
RND_B_ROT_DEC <- 08 C5 7B 41 35 27 12 93
-> 02 AF 8D 1C D7 3F AD 69 B2 77 08 C5 7B 41 35 27 12 93 8F 92
<- 02 00 84 48 EE C5 AB 0D A9 5D 20 68
RND_A_RECIVED <- 84 48 EE C5 AB 0D A9 5D
RND_B_ROT_ENC <- 08 C5 7B 41 35 27 12 93
RND_A_RECIVED_DEC <- BB CC DD AA BB CC DD AA
SessionKey @ ArrForDes <- AA BB CC DD 40 3B 8B 60 AA BB CC DD 40 3B 8B 60
-> 03 45 61 21
<- 03 00 0B 01 EC 86
NewKey
<- 00 00 00 00 00 00 00 00 08 09 0A 0B 0C 0D 0E 0F
KeyData
<- 00 00 00 00 00 00 00 00
<- 08 09 0A 0B 0C 0D 0E 0F
<- FC 41 00 00 00 00 00 00
DecryptedKeyData
<- ED 34 B2 30 D3 49 01 8D
<- 8C E5 10 DC B5 CB 05 9E
<- 1D F0 9D 59 DE B3 00 5A
-> 02 C4 00 ED 34 B2 30 D3 49 01 8D 8C E5 10 DC B5 CB 05 9E 1D F0 9D 59 DE B3 00 5A 65 DC
<- 02 00 10 2D

Как что поясню позже. Пока что чистые логи.
Как видите, здесь используется нативная команда авторизации 0a, она несколько отличается от 1a (standard mode).
Обратите внимание, все данные в нативном режиме только дешифруются, но не шифруются.

Re: Ковыряем RFID Mifare и MFRC522

Сб ноя 25, 2017 20:18:59

Добрый день, а есть у кого-то programming manual к mfrc522?
Или описание как инициализировать модуль для идентификации карт?

подключил я модуль к stm32f103, переписал немного либу, которая ходит по интенету, тесты прогнал
а что дельше делать?

вот исходный код
https://github.com/nmuntyanov/stm32f103 ... src/main.c

Re: Ковыряем RFID Mifare и MFRC522

Пн ноя 27, 2017 00:28:22

Добрый день, а есть у кого-то programming manual к mfrc522?
Или описание как инициализировать модуль для идентификации карт?

подключил я модуль к stm32f103, переписал немного либу, которая ходит по интенету, тесты прогнал
а что дельше делать?

вот исходный код
https://github.com/nmuntyanov/stm32f103 ... src/main.c

Даташит тут - https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf
Вернитесь на страницу обратно, там есть вся информация которая поможет вам понять все аспекты работы с mfrc522. Там даже код есть в процедурном так сказать виде.
viewtopic.php?p=3216806#p3216806

К вопросу о инициализации
//Софтверный ресет
Write(0x01,0x0F);

//Конфигурируем mfrc522
Write(0x11,0x3D);
Write(0x2D,0x30);
Write(0x2C,0x00);
Write(0x2A,0x8D);
Write(0x2B,0x3E);
Write(0x14,0x83);
Write(0x15,0x40);

//Настройка усиления антенны 0x30, 0x40, 0x50, 0x60, 0x70 - максимум
Write(0x26,0x40);

Добавлено after 29 minutes 28 seconds:
Журналирую.

На текущий момент обрел понимание того как работать с ключами и алгоритмами шифрования последних.
DES/3DES
2k3DES
3k3DES

DES использует криптонагрузку на 8 байт.
Можно использовать и 3DES, результат будет аналогичным, так как выражен в виде - des_enc(1st 8byte_key) / des_dec(1st 8byte_key) / des_enc(1st 8byte_key) результат подобной процедуры выполнится в три раза медленнее, а вот сам ключ будет аналогичным одному проходу des_enc(1st 8 byte_key)
3des для шифрования, особенно ключами предназначенными для DES использовать никакого практического смысла нет.
----------
| 01 02 03 04 05 06 07 08 | 01 02 03 04 05 06 07 08 | 01 02 03 04 05 06 07 08 |
----------

2K3DES где полезная нагрузка ключа уже имеет длину 16 байт (128 бит) и 9 - 16 байты отличаются от первых восьми, а вот 17 - 24 являются копией первых 8 байт.
----------
| 01 02 03 04 05 06 07 08 | 0a 0b 0c 0d 0e 0f 0a 0b | 01 02 03 04 05 06 07 08 |
----------

3k3des - 192 битный монстр. Классная штука, если только вы не используете AES :) который быстрее и имеет более серьезную криптографическую стойкость.
----------
| 01 02 03 04 05 06 07 08 | 0a 0b 0c 0d 0e 0f 0a 0b | AA 20 BB CC 50 EE 70 80 |
----------

Пример для DES
Ключ
<- 05 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00
Криптограмма
<- 05 00 00 00 00 00 00 00
<- 05 00 00 00 00 00 00 00
<- 24 78 00 00 00 00 00 00
Шифр
<- EE FA E1 7F 78 A2 35 A8
<- C0 92 9F A2 E7 60 F3 8C
<- 0A FE CD FA 9C C6 42 A5

Пример для 2k3des
Ключ
<- 04 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
Криптограмма
<- 04 00 00 00 00 00 00 00
<- 05 00 00 00 00 00 00 00
<- 34 F6 00 00 00 00 00 00
Шифр
<- BC 48 66 E9 23 76 F9 65
<- 30 ED E7 F4 F5 5D EE E5
<- EA 81 27 A6 22 C7 68 97

В конечном итоге надо понимать, что Desfire не использует 3des, скорее то, что многие понимают под 3des в отношении к
Desfire с практической стороны ни что иное как 2k3des (Two keys 3des).
DES - 1 ключ (56 бит).
2k3DES - два ключа (128 бит).
3k3DES - три ключа (192 бит).
В сухом остатке:
des/2k3des/3k3des/Aes.
Все что потребуется для работы.

Нативная авторизация 0a для des/2k3des.
1a для 3k3des.
aa для aes.

Лог смены 2k3des на аналогичный ключ в нативном режиме работы.
<- 44 03
-> 93 20
<- 88 04 78 8C 78
-> 93 70 88 04 78 8C 78 BC E7
<- 24 D8 36
-> 95 20
<- DA 49 34 80 27
-> 95 70 DA 49 34 80 27 A4 E1
<- 20 FC 70
-> E0 20 3B D6
<- 06 75 77 81 02 80 02 F0
-> 02 5A AA BB CC 6D B1
<- 02 00 10 2D
-> 03 0A 00 00 B7
<- 03 AF AE 37 AB 8E AA 8A 0F 9A 0C 3C
CurrentKey <- 04 00 07 00 00 00 00 00 05 00 00 00 00 00 00 00 04 00 07 00 00 00 00 00
RND_B_RECIVED <- AE 37 AB 8E AA 8A 0F 9A
RND_A <- 01 02 03 04 05 06 07 08
RND_A_ENC <- 45 D5 10 0F E2 8A 5C 9C
RND_B_DEC <- 70 AB A0 56 2E 43 93 7A
<- 01 02 03 04 70 AB A0 56 05 06 07 08 2E 43 93 7A 01 02 03 04 70 AB A0 56
RND_B_ROT <- AB A0 56 2E 43 93 7A 70
RND_B_ROT_ENC <- 3D C0 E4 7E 42 E7 12 38
-> 02 AF 45 D5 10 0F E2 8A 5C 9C 3D C0 E4 7E 42 E7 12 38 EE FB
<- 02 00 8E 0F C7 EA BA 33 51 76 25 80
RND_A_RECIVED <- 8E 0F C7 EA BA 33 51 76
RND_A_RECIVED_DEC <- 02 03 04 05 06 07 08 01
SessionKey @ ArrForDes <- 01 02 03 04 70 AB A0 56 05 06 07 08 2E 43 93 7A 01 02 03 04 70 AB A0 56
NewKey
<- 04 00 07 00 00 00 00 00 05 00 00 00 00 00 00 00
DataBlocks
<- 04 00 07 00 00 00 00 00
<- 05 00 00 00 00 00 00 00
<- B3 86 00 00 00 00 00 00
EncryptedKeyData
<- 10 A2 92 42 17 C0 15 3F
<- CE 42 2E C0 67 52 99 1A
<- 61 80 E2 57 58 8D 3E F1
-> 03 C4 00 10 A2 92 42 17 C0 15 3F CE 42 2E C0 67 52 99 1A 61 80 E2 57 58 8D 3E F1 D0 6F
<- 03 00 C8 34

Для 2k3des SessionKey в отличии от DES формируется иначе (см. пост выше с авторизацией DES).
Здесь 1st RNA_A + 1st RND_B + 2st RND_A + 2st RND_B + 1st RNA_A + 1st RND_B

Что подходит под критерии ключа 2k3des где первые 8 байт и последние 8 байт являются копией.
То-есть: два уникальных ключа.
----------
| 01 02 03 04 40 96 BF CF | 05 06 07 08 86 1F 48 8E | 01 02 03 04 40 96 BF CF |
----------
Ответить