Расшифровка данных зашифрованной дорожки DUKPT

Как следует из названия, я пытаюсь расшифровать данные зашифрованной дорожки DUKPT, поступающие со сканера с поддержкой DUKPT.

У меня есть стандарт ANSI (X9.24) для DUKPT и я успешно реализовал возможность генерировать IPEK из KSN и BDK. Кроме того, я успешно реализовал возможность генерировать левый и правый ключи MAC-запросов и ответов, XORing ключи шифрования PIN-кода. Наконец, я могу генерировать EPB.

Отсюда я не понимаю, как сгенерировать MAC-запрос и ответ из L/R-ключей, которые я сгенерировал.

И наконец, как только я доберусь до этого шага, что будет дальше? Когда у меня действительно есть ключ, который расшифровывает данные трека, отправленные устройством с поддержкой DUKPT?

Мне известны симулятор Thales и jPOS. Мой код в настоящее время ссылается на симулятор Thales для выполнения всей своей работы. Но процесс расшифровки файла просто не возвращает ожидаемые данные.

Если кто-нибудь может предложить какое-то понимание расшифровки данных трека, это будет очень цениться.

http://thalessim.codeplex.com/

http://jpos.org/

2 ответа

Решение

Я потратил слишком много времени на изучение ужасной спецификации X9.24 и, наконец, получил шифрование и дешифрование, работая с примерами моего поставщика, и маркетинг быстро решил сменить поставщика. Поскольку это стандарт, вы могли бы подумать, что чья-либо реализация будет такой же. Хотелось бы. Во всяком случае, есть варианты того, как все реализовано. Вы должны изучить мелкий шрифт, чтобы убедиться, что вы работаете так же, как ваша другая сторона.

Но это не твой вопрос.

Во-первых, если вам нужно расшифровать дорожку данных с кредитной карты, вы, вероятно, заинтересованы в создании ключа, который расшифровывает данные на основе оригинального сверхсекретного ключа базовой деривации. Это не имеет ничего общего с генерацией MAC и упоминается только в этой ужасной спецификации. Вам необходимо сгенерировать IPEK для этого серийного номера ключа и идентификатора устройства и повторно применить "Процесс необратимого генерирования ключа" из спецификации, если биты установлены в счетной части полного серийного номера ключа от HSM.

Эта часть моего кода выглядит следующим образом: (Извините за длинный список в публикации.)

/*
 * Bit "zero" set (this is a 21 bit register)(ANSI counts from the left)
 * This will be used to test each bit of the encryption counter
 * to decide when to find another key.
 */
testBit=0x00100000;
/*
 * We have to "encrypt" the IPEK repeatedly to find the current key
 * (See Section A.3).  Each time we encrypt (generate a new key),
 * we need to use the all prior bits to the left of the current bit.
 * The Spec says we will have a maximum of ten bits set at any time
 * so we should not have to generate more than ten keys to find the
 * current encryption key.
 */
cumBits=0;
/*
 * For each of the 21 possible key bits,
 * if it is set, we need to OR that bit into the cumulative bit
 * variable and set that as the KSN count and "encrypt" again.
 * The encryption we are using the goofy ANSI Key Generation
 * subroutine from page 50.
 */
for(int ii=0; ii<21; ii++)
{
    if( (keyNumber&testBit) != 0)
    {
        char ksr[10];
        char eightByte[8]={0};

        cumBits |= testBit;
        ksn.count=cumBits;   /* all bits processed to date */

        memcpy(ksr, &ksn,10);       /* copy bit structure to char array*/
        memcpy(crypt,&ksr[2],8);    /* copy bytes 2 through 9 */

        /*
         * Generate the new Key overwriting the old.
         * This will apply the "Non-reversible Key Generation Process"
         * to the lower 64 bits of the KSN.
         */
        keyGen(&key, &crypt, &key);
    }
    testBit>>=1;
}

Где keyNumber - текущий счетчик от ksn. Ksn - это 80-битная структура, которая содержит 80-битный серийный номер ключа из крипты HSM - это 64-битный блок данных, у меня он типа DES_cblock, так как я использую openSSL. ключ представляет собой 128-битную двойную структуру DES_cblock. Процедура keyGen почти дословно из локальной подпрограммы "Процесс необратимого генерирования ключа" на странице 50 спецификации.

В конце этого, переменная key будет содержать ключ, который можно использовать почти для расшифровки. Парни, которые написали спецификацию, добавили к ключу "вариантное" поведение, чтобы держать нас в тонусе. Если ключ должен использоваться для дешифрования потока данных, такого как дорожка кредитной карты, вам потребуется XOR байтов 5 и 13 с 0xFF, а Triple DES зашифрует ключ сам (режим ECB). Мой код выглядит так:

DOUBLE_KEY keyCopy;
char *p;
p=(char*)&key;
p[ 5]^=0xff;
p[13]^=0xff;
keyCopy=key;
des3(&keyCopy, (DES_cblock *)&key.left,  &key.left);
des3(&keyCopy, (DES_cblock *)&key.right, &key.right);

Если вы используете это для расшифровки блока ПИН-кода, вам потребуется XOR байтов 7 и 15 с 0xFF. (Я не уверен на 100%, что это не должно применяться и к потоковому режиму, но мой поставщик оставляет его без внимания.)

Если это блок PIN, он будет зашифрован с помощью 3-DES в режиме ECB. Если это поток данных, он будет зашифрован в режиме CBC с нулевым вектором инициализации.

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

Удачи. Боб Брайан

Для шифрования данных вариант 0000000000FF0000.0000000000FF0000 поэтому вам нужно XOR байты 5 и 13 вместо 7 и 15. Кроме того, вам необходим дополнительный шаг самокодировки 3DES для каждой ключевой части (левой и правой).

Вот соответствующий код в jPOS https://github.com/jpos/jPOS/blob/master/jpos/src/main/java/org/jpos/security/jceadapter/JCESecurityModule.java#L1843-1856

Другие вопросы по тегам