Механизм нативной авторизации
-> 02 5A AA BB CC 6D B1
<- 02 00 10 2D
-> 03 0A 00 00 B7
<- 03 AF 96 F1 76 F9 8A B5 9B 67 B0 A1
CurrentKey <- 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
RND_B_RECIVED <- 96 F1 76 F9 8A B5 9B 67
RND_A <- 01 02 03 04 05 06 07 08
RND_A_DEC <- C7 65 26 59 B5 BD D7 F3
RND_B_DEC <- 62 02 F4 6E 6F 75 76 63
RND_B_ROT <- 02 F4 6E 6F 75 76 63 62
RND_B_ROT_DEC <- 2B 38 19 1B 90 D8 55 1A
-> 02 AF C7 65 26 59 B5 BD D7 F3 2B 38 19 1B 90 D8 55 1A D3 F0
<- 02 00 53 F4 CF F3 A4 8B AF 0B 25 85
RND_A_RECIVED <- 53 F4 CF F3 A4 8B AF 0B
RND_A_RECIVED_DEC <- 02 03 04 05 06 07 08 01
Но почему мой SessionKey отличается от данных выше?
SessionKey <- 00 02 02 04 62 02 F4 6E 04 06 06 08 6E 74 76 62 00 02 02 04 62 02 F4 6E
В пред идущем посте я упомянул о нулевом бите каждого байта.
"NXP рекомендует сбрасывать данный бит в 0, дабы усложнить задачу взломщику." и даже привел простейшую функцию на C, которая реализует данный механизм.
Заранее создано приложение 0xAA 0xBB 0xCC с версией ключа 0x00.
0x0A - нативная авторизация. На что карта возвращает нам RND_B 96 F1 76 F9 8A B5 9B 67
Генерируем свой (любой) RND_A или используем заранее подготовленный (не имеет значения)
RND_A <- 01 02 03 04 05 06 07 08
Теперь используя 3des (или DES, все зависит от того, какой тип ключа использует ваша карта) производим ВНИМАНИЕ DEcrypt
вашего RND_A. Да, именно ДЕ-шифровку, так как карта умеет только шифровать, но не ДЕ-шифровать.
И по логике, если вы де-шифруете данные, то карта шифруя их аналогичным ключом - получит правильные данные.
RND_A_DEC <- C7 65 26 59 B5 BD D7 F3 это де-шифрованный RND_A <- 01 02 03 04 05 06 07 08
Теперь де-шифруем RND_B полученный ранее.
Производим сдвиг влево << на 8 бит.
И производим ДЕ-шифровку в режиме CBC, где в качестве вектора используем ранее дешифрованный RND_A_DEC.
В результате на выходе у вас
RND_A_DEC <- C7 65 26 59 B5 BD D7 F3
RND_B_ROT_ENC <- 2B 38 19 1B 90 D8 55 1A
Которые необходимо отправить карте
-> 02 AF
C7 65 26 59 B5 BD D7 F3 2B 38 19 1B 90 D8 55 1A D3 F0
Далее очень важно понять. Карта произведет шифрование полученных данных, и если RND_B высланный вами ранее совпадет, то карта, не зависимо от того, правильно ли вы сформировали RND_A, или не правильно, ответит вам:
<- 02
00 53 F4 CF F3 A4 8B AF 0B 25 85
00 - авторизация верна.
Но не факт, что верен RND_A, а его правильность повлияет на SessionKey, который необходимо для дешифровки дальнейших данных отправляемых карте.
Далее для проверки правильности RND_A мы его просто расшифровываем без IV-вектора.
RND_A_RECIVED <- 53 F4 CF F3 A4 8B AF 0B
RND_A_RECIVED_DEC <- 02 03 04 05 06 07 08 01
Как видите, присланный картой RND_A совпадает с нашим, за исключением того, что он сдвинут на 8 бит влево, и необходимо подвинуть на 8 бит в обратную сторону.
Мой SessionKey <- 01 02 03 04 93 68 22 50 05 06 07 08 A5 9F 78 CC 01 02 03 04 93 68 22 50
В данном случае использовался ключ 2k3des, а значит SessionKey состоит из:
Первой половины RND_A, первой половины RND_B, второй половины RND_A, второй половины RND_B
В случае с DES:
Первой половины RND_A, первой половины RND_B, опять первой половины RND_A, и опять первой половины RND_B
SessionKey всегда равен 16 байтам.
Это был правильный нативный алгоритм работы который проверен на моей карте Desfire EV1.
Где то я находил информацию о том, что данный механизм для EV1 уже устарел, и необходимо авторизовать карту иначе. Но дело в том что пока эти данные я не подтвердил но и не опроверг.
Теперь о смене ключа.
NewKey
<- 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00
DataBlocks
<- 05 00 00 00 00 00 00 00
<- 00 00 00 00 00 00 00 00
<- 45 EF 00 00 00 00 00 00
DecryptedKeyData
<- 06 26 8B 06 4A BA 55 09
<- E6 13 2C 3A 2B 89 50 C3
<- EE AB 5C 19 D4 AF D6 98
-> 02 C4 00 06 26 8B 06 4A BA 55 09 E6 13 2C 3A 2B 89 50 C3 EE AB 5C 19 D4 AF D6 98 D0 5A
<- 02 00 10 2D
Механизм простой.
Участники - SessionKey, NewKey, Три блока по 8 байт:
1 - Первая часть нового ключа
2 - Вторая часть нового ключа
3 - Два байта crc16 (нового ключа - 16 байт) + так называемый padding из 00 00 00 00 00 00, так как блоки должны быть кратными 8-ми байтам.
Далее при помощи SessionKey и первого начального вектора из 8-ми нулей, производим ДЕ-шифровку первого блока
<- 06 26 8B 06 4A BA 55 09
Затем производим ту же операцию над вторым блоком, но в качестве вектора используем первый дешифрованный блок.
<- E6 13 2C 3A 2B 89 50 C3
Аналогично, но в качестве вектора используем второй дешифрованный блок.
<- EE AB 5C 19 D4 AF D6 98
Теперь данные отправляются карте:
-> 02 C4 00
06 26 8B 06 4A BA 55 09 E6 13 2C 3A 2B 89 50 C3 EE AB 5C 19 D4 AF D6 98 D0 5A
C4 00 - изменить ключ 00.
Дешифрованная строка.
D0 5A - crc16 дешифрованной строки.
В моем случае ответ:
<- 02 00 10 2D
Ключ успешно изменен.
Еще немного о шифре.
Карта с завода шифрована восемью нулями при помощи DES (0x00).
Авторизовать ее можно просто используя SingleDES.
3DES используем только для двух или трех уникальных ключей (2k3des,3k3des).
DES, 2k3DES, 3k3DES! Три алгоритма.
Других DES алгоритмов картой не предусмотрено, хотя возможность есть.
Очевидно, не имеет смысла использовать 3des в связке с одним уникальным ключом (8 байт) понапрасну расходуя ограниченные ресурсы процессора.
Единственный резон всегда использовать 3des, только в том случае, если вы не знаете какой ключ установлен на карте, но вы то об этом знаете.
Пробираюсь дальше. В следующих сериях AES, Read/Write, CMAC, тесты производительности и финал.
