Как расшифровать данные магнитной дорожки с использованием DUKPT

Как расшифровать данные магнитной дорожки с использованием DUKPT

730
ПОДЕЛИТЬСЯ

Предлагаю читателям «Хабрахабра» перевод статьи «How To Decrypt Magnetic Card Data With DUKPT».

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

Мысль данной схемы состоит в том, что для каждой транзакции (либо в нашем случае для каждого проката карты) данные шифруются с внедрением ключа вычисленного для отдельного проката карты. Оказалось, мои считыватели употребляют схему известную как DUKPT (Derived Unique Key Per Transaction — Определение Неповторимого Ключа На Транзакцию).

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

Наилучший ресурс, который мне удалось отыскать, здесь; там достаточно не плохое разъяснение как рассчитывается IPEK (Initial Pin Encryption Key — исходный ключ для вычисления ключей). Но документ стоит приблизительно $140. Процесс описан в документе ANSI X9.24 part 1. В этом посте я попробую всесторонне разъяснить схему DUKPT. К огорчению, это лишь часть полной схемы. Бесплатную, просто-доступную документацию, описывающую этот процесс, тяжело отыскать.

Определения
BDK: Это сокращение от Base Derivation Key (базисный ключ метода). Этот ключ известен лишь производителю и разрабу софта, взаимодействующего со сканером магнитных дорожек.

Этот ключ загружается на устройство производителем и употребляется для генерации будущих ключей. Этот ключ определяется из BDK. Компрометация IPEK не компрометирует BDK. IPEK: Это сокращение от Initial Pin Encryption Key (исходный ключ для вычисления ключей).

KSN это композиция серийного номера сканера магнитных дорожек и счетчика количества прокатов карты, которое было выполнена на устройстве. KSN: Это сокращение от Key Serial Number (Серийный номер ключа).

Как оно работает
Устройство употребляет IPEK и KSN для вычисления сессионного ключа, которым шифруются данные читаемые с карты. BDK употребляется производителем для генерации IPEK, который загружается на устройство во время разработки.

IPEK и KSN употребляются для получения ключа на отдельную транзакцию/прокат карты. Имея эти ключи, создатели могут расшифровать карточные данные. Получив IPEK, они могут запросить KSN у устройства. BDK требуется разрабам софта для вычисления IPEK.

Вычисление IPEK
TripleDES это обычный метод DES выполняемый в три прохода. Чтоб получить исходный ключ для вычисления ключей (IPEK), нам нужен базисный ключ метода (BDK) и серийный номер ключа (KSN). IPEK определяется с помощью метода TripleDES.

Метод употребляет ключ длиной 24 б. Употребляется метод DES три раза поначалу с ключом с 1-8 б, потом 9-16 б и, в конце концов, 17-24 б раздельно за каждый проход.

TripleDES может применять ключ длиной 16 б, таковой способ именуется EDE3. Будут употребляться поначалу байты 1-8, потом 9-16 и, опять, 1-8 эмитируя 24-х байтовый ключ.

Перед тем как это осознать я издержал много времени пытаясь разобраться в чем неувязка. Некие реализации TripleDES не могут автоматом применять маленький ключ. Предположив что это особенная реализация TripleDES я употреблял эмитированный 24 байтовый ключ из 16 байтов.

Опосля длительных мучений на меня снизошло испытать взять 1-ые 8 б и добавить их в конец ключа перед тем, как передать его в TripleDES метод. Это решило делему.

Подробности
Разница меж левой и правой частями в том, что правая часть выходит шифрованием KSN с помощью незначительно модифицированной версии BDK. IPEK состоит из 2-ух 8-ми байтовых частей, которые получаются в итоге 2-ух отдельных проходов метода TripleDES. Оба получаются с помощью шифрования старших 8 б KSN с обнуленным счетчиком. Я обрисую этот процесс ниже.

Представим, имеется 16 байтовый BDK представленный шестнадцатеричной строчкой «0123456789ABCDEFFEDCBA9876543210». Также имеем 10 байтовый KSN со счетчиком равным 8, представленный шестнадцатеричной строчкой «FFFF9876543210E00008».

Получим BDK для шифрования левой части IPEK добавлением первых 8 б в конец BDK, это будет последующий 24 байтовый ключ.

0123456789ABCDEFFEDCBA98765432100123456789ABCDEF
Это означает, что мы вычисляем его со счетчиком в KSN равным 0. Чтоб получить KSN со счетчиком 0, мы накладываем на него маску шестнадцатеричным представлением которой является строчка «FFFFFFFFFFFFFFE00000». Раз длина KSN не равна 10 б, то дополняем его до 10 б шестнадцатеричной «F» (1111). Принципиально отметить, что IPEK является самым первым ключом на устройстве.

FFFF9876543210E00008
and FFFFFFFFFFFFFFE00000
= FFFF9876543210E00000
Мы получаем их, сдвигая KSN на право на 16 бит. Замечательно. Но нам необходимы старшие 8 б KSN. Сейчас у нас есть нулевой KSN.

FFFF9876543210E00000 >> 16 = FFFF9876543210E0
Последующий шаг — TripleDES шифрование строчки «FFFF9876543210E0» с помощью ключа BDK в 24 б «0123456789ABCDEFFEDCBA98765432100123456789ABCDEF». Непревзойденно. Результатом этого шифрования будет левая часть IPEK.

6AC292FAA1315B4D
Похоже это на сто процентов случайная маска, но как досадно бы это не звучало, она нужна для получения верного IPEK. Раз вы помните, я упоминал что для получения правой часть будет употребляться незначительно модифицированная версия BDK. Таковым образом, чтоб сделать это, нам необходимо взять уникальный 16 байтовый BDK «0123456789ABCDEFFEDCBA9876543210» и выполнить XOR по последующей маске «C0C0C0C000000000C0C0C0C000000000».

0123456789ABCDEFFEDCBA9876543210
xor C0C0C0C000000000C0C0C0C000000000
= C1E385A789ABCDEF3E1C7A5876543210
Мы создадим тоже самое, что делали с ключом для левой части, возьмем старшие 8 б и добавим их в конец, получится последующий 24 байтовый ключ.

C1E385A789ABCDEF3E1C7A5876543210C1E385A789ABCDEF
Это даст нам правый регистр IPEK, получаем последующий 16 байтовый IPEK (я поделил левую и правую части для ясности). Дальше возьмем старшие 8 б KSN с нулевым счетчиком (который мы вычисляли ранее) и зашифруем его с помощью TripleDES ключом который лишь что вычислили.

6AC292FAA1315B4D 858AB3A3D7D5933A
Вычисление сессионных ключей
Дальше нам необходимо получить из IPEK неповторимый ключ для отдельного проката карты (сессионный ключ). У нас есть IPEK. Прямо на данный момент мы поглядим на вход данной подпрограммы. Чтоб получить его, употребляется некоторая подпрограмма, назовем ее темный ящик, целью которой является возврат отдельного сессионного ключа. Происходящее в черном ящике — пока не наша забота.

Строчка представляет собой модифицированный KSN. Один это ключ и 2-ой — строчка для шифрования. Наш темный ящик имеет два входа.

Ключ который передается с модифицированным KSN это IPEK на первой итерации, а на последующих итерациях это будет ключ приобретенный из темного ящика на предшествующей итерации. Мы передадим измененный KSN в подпрограмму столько раз, сколько единиц в бинарном представлении счетчика. Раз помните, младшие 21 бит KSN содержат счетчик количества прокатов карты на устройстве.

Это можно сделать с помощью маскирования KSN с внедрением последующей маски. Для начала мы возьмем младшие 8 б KSN и обнулим значение счетчика в KSN. Начнем с конфигурации KSN.

FFFF9876543210E00008
and 0000FFFFFFFFFFE00000
= 00009876543210E00000
Приобретенное значение мы будем применять для вычисления каждого сообщения передаваемого в темный ящик. Для демонстрации представим, что счетчик имеет наиболее сложное значение 10 (1010). В нашем примере со счетчиком равным 8 мы должны передать в темный ящик двоичное представление числа 8 (1000).

В нашем случае для числа 10 (1010) будет два двоичных числа: 1000 и 0010. Вы поймали схему? Мы будем извлекать набор двоичных чисел из счетчика. Мы получаем набор чисел, представляющих каждую бинарную единицу числа 10.

Дальше берем 1-ое число и применяем операцию OR с KSN, у которого обнулен счетчик, как было показано ранее (заметим что шестнадцатеричное представление первого числа будет 0008).

9876543210E00000
OR 0000000000000008
= 9876543210E00008
Это 1-ый сессионный ключ (представленный в шестнадцатеричном виде): «27f66d5244ff62e1aa6f6120edeb4280». Сейчас передаем IPEK как ключ и лишь что измененный KSN в темный ящик. Темный ящик вернет новейший ключ.

Дальше повторим процесс со последующим двоичным числом, вычисленным ранее, 2 (0010). На этот раз, мы будем применять 1-ый сессионный ключ, который мы лишь что получили и вычислим новейшую модификацию KSN.

Для вычисления новейшей модификации KSN мы будем делать операцию OR с крайней приобретенной модификацией: 9876543210E00008.

9876543210E00008
OR 0000000000000002
= 9876543210E0000A
Сейчас передадим наш новейший ключ «27f66d5244ff62e1aa6f6120edeb4280» и новейшую модификацию KSN «9876543210E0000A» в темный ящик и получим иной будущий ключ, «6cf2500a22507c7cc776ceadc1e33014». Это сессионный ключ для нашего устройства со счетчиком 10.

Но, наш реальный счетчик был равен 8, а реальный сессионный ключ «27F66D5244FF62E1AA6F6120EDEB4280» мы вычислили на первом шаге.

Крайняя операция, которую мы должны сделать с приобретенным значением, конечное преобразование ключа, которым мы будем расшифровывать данные. Мы должны выполнить XOR ключа с маской «00000000000000FF00000000000000FF».

27F66D5244FF62E1AA6F6120EDEB4280
XOR 00000000000000FF00000000000000FF
= 27F66D5244FF621EAA6F6120EDEB427F
Это ключ, который требуется для расшифрования данных.

Темный ящик
Чёрным ящиком я именовал метод, который вычисляет сессионные ключи. Темный ящик воспринимает текущий сессионный ключ, который я обозначу current_sk, и модификацию KSN, обозначим ksn_mod.

Раз в начале предположение что IPEK приобретенный выше был передан как current_sk, а ksn_mod был равен значению «9876543210E00008», которое мы вычислили выше.

Для начала нам необходимо взять current_sk, получить старшие 8 б и двинуть их на 64 бита на право, получим «6AC292FAA1315B4D». Это можно получить с помощью битовой маски.

6AC292FAA1315B4D858AB3A3D7D5933A
AND FFFFFFFFFFFFFFFF0000000000000000
= 6AC292FAA1315B4D0000000000000000
Тут нам необходимо двинуть это значение на 64 бита на право, чтоб получить «6AC292FAA1315B4D». Назовем его left_key (смотрится как левая часть current_sk).

Дальше получим 8 младших б current_sk, с помощью маски.

6AC292FAA1315B4D858AB3A3D7D5933A
AND 0000000000000000FFFFFFFFFFFFFFFF
= 0000000000000000858AB3A3D7D5933A
Давайте назовем это значение (вы додумались) right_key. Дальше возьмем right_key и выполним XOR с ksn_mod «9876543210E00008».

858AB3A3D7D5933A
AND 9876543210E00008
= 1DFCE791C7359332
Получится значение «2FE5D2833A3ED1BA». Это значение назовем message. Дальше берем message и шифруем его с помощью DES (обычный DES). Сейчас необходимо выполнить XOR этого значения и right_key. Будем передавать в DES метод message как данные, которые нужно закриптовать, и left_key, как ключ которым нужно зашифровать.

2FE5D2833A3ED1BA
XOR 858AB3A3D7D5933A
= AA6F6120EDEB4280
Сейчас нам нужно повторить лишь что описанные операции с иными входными данными. Как я могу судить это значение произвольно, но оно часть эталона ANSI, так что вы просто должны поверить моим словам. На этот раз мы берем current_sk и исполняем XOR его с «C0C0C0C000000000C0C0C0C000000000». Это значение младшие 8 б нашего сессионного ключа!

6AC292FAA1315B4D858AB3A3D7D5933A
XOR C0C0C0C000000000C0C0C0C000000000
= AA02523AA1315B4D454A7363D7D5933A
Раз мы возьмем значение «AA02523AA1315B4D454A7363D7D5933A» и подставим его заместо current_sk в операцию, которая описана выше, мы получим «27F66D5244FF62E1». Это старшие 8 б нашего сессионного ключа. Комбинируя их получим «27F66D5244FF62E1AA6F6120EDEB4280».

Заключение
Жду исправления и вопросцы в секции комментариев. habrahabr.ru Надеюсь, я объяснил схему DUKPT и как она относится к эффективности сканеров магнитных дорожек.