Так, в общем требуется собрать много информации прежде чем я опубликую работу с авторизацией. Механизм не очень простой. Если у кого что есть ценное по этой теме сказать - пишите.
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 - Листаем. Так вот, у меня на данную команду карта не реагирует.
Конечно же ошибка с моей стороны, так как стандарт явно описывает формирование заголовка и тела команды. Есть строгие правила, но я пока не в теме как их выполнять.
Так, ну что, начнем выяснять что делаю не так. С простой командый - 60h - версия карты. Пока что ничего не выходит. Команда ничего не отдает. Знаю, что есть обертка по ISO 7816, но и в этой обертке я ничего от карты получить не могу. Единственная команда на которую карта хоть что то отвечает - 0a - авторизация. Но прежде чем делается авторизация вообще то должен быть выполнен селект.
Добавлено 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 (ИМХО!) Вообще давайте сразу определимся - я не учу работать с картами, я журналирую свои действия, не более того! Продолжение следует.
Сравните с логом сверху. Разница проста: Без обертки не фигурируют операции чтения 89 и записи байта данных 09. Чистые куски лога требуются для общения в комьюнити MIFARE. Во всяком случае предполагается.
Если кто будет писать свой софт - сообщите. Хорошо бы на СИ все это дело завернуть. Особенно, когда потребуются функции для побитовых операций XOR, калькуляции и работы с шифрованием.
Добавлено after 3 hours 36 minutes 25 seconds: Эх, теперь все клеится к одному посту. Интересно, как долго движок форума будет клеить мессаги? Ну, не суть. Продолжаем. Сейчас будем пробовать листать ответ и поймем что он значит. <- 02 AF 04 01 01 01 0018 05 88 B9crc 02 AF - AF означает что данные не переданы полностью и требуется листинг. 01 00 - тут должна быть версия (но не факт), вышло что версия карты 00 (такого не может быть). 18 - storage size is 18 (4096 bytes) - 4k - это факт, карта действительно 4k. 04 - я так понимаю что это количество байт в поле body ответа. Поле body - 01 0018 05 В общем без доки понятно что ничего не понятно, ничто не понято и интерпретировано из рук вон плохо!
По поводу 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 BA44 93 99 4024 13 27 44 93 99 40 - серийный номер. Вообще он должен иметь пять байт, но не факт. Если серийный номер пятизначный то тогда поменяли год и неделю местами в новых картах. 44 93 99 40 2413 27 - 13 год 27 неделя. Если не меняли ничего, то 24 13 - Карта произведена на 24-ю неделю 13 года. Но куда прилепить 27 )) 5E 6F DA 49 34 80 BA - UID
Открыта удобная площадка с выгодными ценами, поставляющая весь ассортимент продукции, производимой компанией MEAN WELL – от завоевавших популярность и известных на рынке изделий до новинок. MEAN WELL.Market предоставляет гарантийную и сервисную поддержку, удобный подбор продукции, оперативную доставку по России.
На сайте интернет-магазина посетители смогут найти обзоры, интересные статьи о применении, максимальный объем технических сведений.
Авторизация. Процедура: 1 - Выборали приложение. Приложение на пустой карте только одно - 00 00 00 2 - Авторизовались. Ключ 16 или 8 нулей, а то и 15. Будем посмотреть. Метод шифрования по умолчанию 3des
Команда 45 показывает конфигурацию ключа (права доступа). 0F01 01 - количество ключей доступное для данного приложения. Мастер ключ - только один. 0А - [00001111] - права.
Продукция MOSO предназначена в основном для индустриальных приложений, использует инновационные решения на основе более 200 собственных патентов для силовой электроники и соответствует международным стандартам. LED-драйверы MOSO применяются в системах наружного освещения разных отраслей, включая промышленность, сельское хозяйство, транспорт и железную дорогу. В ряде серий реализована возможность дистанционного контроля и программирования работы по заданному сценарию. Разберем решения MOSO
подробнее>>
maddogmaycry
Заголовок сообщения: Re: Ковыряем RFID Mifare и MFRC522
Короч, че то у меня странно 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 будет сводить эту полосу в четыре раза. ИМХО.
Код для arduino,- авторизация пока не работает, к ней я в настоящий момент подхожу. Работает поверх i2c.
Потребуется ардуинка с хорошим регулятором питания на 3.3в. У меня AMS1117-3.3. На моей atmega2560 плата с плохим стабилизатором и в i2c ведет себя крайне нестабильно. Адрес пляшет, антенна работает плохо. Однако SPI режим на той же плате уже работает хорошо.
//Калькуляция 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(" "); }
//Проверяем 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);
if (error == 0){ Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !");
nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n");
delay(5000); } Программа носит образовательный характер - понять принцип взаимодействия с 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 Спойлер
Код:
//Информация о карте Write(0x09,0x02);Write(0x09,0x60); //CRC калькулировался заранее Write(0x09,0x16);Write(0x09,0x4e); //Отправка Write(0x01,0x0c);Write(0x0d,0x80); delay(1);
Serial.println("Информация о карте"); Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));
//Информация о карте страница 2 Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));
//Информация о карте страница 3 Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));Echo(Read(0x89));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();
Теперь можно прочитать версию карты: Карта 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) и запросим у него инфу о ключе. Далее иду блоками. То-есть: кусочек добавляемого кода и его вывод.
Я уже забыл как читать вывод, но суть там простая. Выделили приложение 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 настройки ключа сообщает что без авторизации можно создавать и удалять аппликации. Может создадим чего для начала
Результат - 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
Авторизация. Суть авторизации 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. Что с ним делать я пока не знаю, но для начала попробую получить именно его.
В общем то ничего сложного по сути нет, будем поглядеть как говорится.
Я тут смотрел в сети народ активно обсуждал разные алгоритмы. Кто то предлагал 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% как эта штука функционирует.
Народ который разобрался в теме и выложил логи, которые не дают полного представления о механике. Вот пример одного из них:
Результат: 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++ выглядит следующим образом
Что бы понимать о чем речь. Возьмем первые два байта: 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. Но не уверен. Все это ИМХО, так как этот вопрос я сейчас и разбираю.
Так, что на данный момент стало известно. 1 - после авторизации обмен данными с картой так же шифруется (схема у NXP как водится своя) не могут эти ребята без танцев с бубном. 2 - Требуется формировать блоки по 8 байт, если пакет больше 8 байт, то устанавливается padding. Допустим пакет имеет длину 12 байт, значит вместе с паддингом получится 16 байт, то-есть кратно 8-ми. 3 - Эти пакеты требуется шифровать/дешифровать методом от NXP http://read.pudn.com/downloads134/ebook ... df#page=29
Приветствую. Долго ничего не выкладывал. Изучал дополнительную информацию. Функция расчета 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); }
Так как MFRC522 возвращает количество байт в буффере HEX значением, не плохо было бы конвертировать это значение в DEC. Я не уверен что POW быстр, но других вариантов я пока не нашел.
Код:
int GetBufferSize(){ return Read(0x8a); }
Чё то я ступил. Оказывается возвращает нормальное значение. Странно. Я был убежден в том что возвращалось HEX значение. Инженеры NXP - зачёт.
Сегодня великий день я авторизовал карту ключом по умолчанию. Ниже лог. <- 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 8FC6 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 AA36 6D B6 12AA BB CC AA36 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 еще раз. В общем пока что тёмный лес
А вот и не так. Дело в том что у карты существуют так называемые уровни. Уровень PICC, app, file. Команда версии работает на уровне PICC, ее шифровать не обязательно ИМХО. Выбор приложения является уровнем APP, и там уже половина команд шифрованная и половина - нет. Например при смене пароля или KEY_SETTINGS на уровне APP то сама команда не шифруется, а вот данные ключа или новых ключевых настроек надо шифровать. На уровне file настройка уровня настраивается. Без шифрования. Защита MAC. Полностью зашифрованное. Это сделано для защиты данных. Между картой и устройством может быть подложен перехватчик, и он может знать какие приложения есть на карте, так как эти данные можно получить на уровне PICC, но никак не что то иное. Все это мое ИМХО основанное на доступной в сети информации которая возможно уже устарела. На пример у карт EV1 устройство может шифровать данные и передавать карте, в то время как старые версии карт умели выполнять только операцию шифрования, и перед отправкой на карту надо было наоборот производить операцию ДЕшифровки. Вот так.
Сегодня попробую при помощи SessionKey поменять ключ в приложении. Напомню, что DES игнорирует 0 бит каждого байта в массиве. Перед использованием SessionKey требуется обработать массив функцией. void ArrForDes(byte *arr,int cnt){ for(int i=0;i<8;i++){ arr[i]&=~(1<<0); } }
Этого можно не делать, но вроде как данные зашифрованные при помощи ключа необработанного подобным образом - можно взломать. Атака вроде как связана с битом состояния который использует 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.
Смена 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). Обратите внимание, все данные в нативном режиме только дешифруются, но не шифруются.
Добавлено 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 | ----------
В конечном итоге надо понимать, что 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 | ----------
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения