Как шифрованный текст был создан в Card reader с использованием шифрования DUKPT?

на

`BDK = "0123456789ABCDEFFEDCBA9876543210"` `KSN = "FFFF9876543210E00008"` 

сгенерированный зашифрованный текст был ниже

"C25C1D1197D31CAA87285D59A892047426D9182EC11353C051ADD6D0F072A6CB3436560B3071FC1FD11D9F7E74886742D9BEE0CFD1EA1064C213BB55278B2F12"`

что я нашел здесь. Я знаю, что этот шифрованный текст основан на BDK и KSN, но как был создан этот шифрованный текст длиной 128? Какие шаги в нем задействованы или алгоритм используется для этого? Может кто-нибудь объяснить простыми шагами. Мне было трудно понять документы, которые я получил, пока гуглил.

4 ответов


о DUKPT , есть некоторые объяснения на Wiki. Если этого вам недостаточно, вот краткое объяснение.

цитирование http://www.maravis.com/library/derived-unique-key-per-transaction-dukpt/

Что такое DUKPT?

производный уникальный ключ для транзакции (DUKPT) - это схема управления ключами. Он использует однократные производные ключи шифрования из секретного главного ключа, совместно используемого сущностью (или устройством), которая шифрует, и сущностью (или устройством), которая расшифровывает данные. Почему DUKPT? Любой алгоритм шифрования так же безопасен, как и его ключи. Самый сильный алгоритм бесполезен, если ключи, используемые для шифрования данных с помощью алгоритма не являются безопасными. Это все равно что запереть дверь самым большим и крепким замком, но если спрятать ключ под ковриком, сам замок бесполезен. Когда мы говорим о шифровании, нам также нужно сохранить в виду, что данные должны быть расшифрованы на другом конце. Как правило, самым слабым звеном в любой схеме шифрования является совместное использование ключей между сторонами шифрования и дешифрования. DUKPT-это попытка гарантировать, что обе стороны могут шифровать и дешифровать данные без шифрования/дешифрования вокруг. Документ о наилучшей криптографической практике, опубликованный VISA, также рекомендует использовать DUKPT для соответствия требованиям PCI DSS.

Как DUKPT Работает

DUKPT использует одноразовые ключи, которые генерируются для каждой транзакции, а затем отбрасываются. Преимущество заключается в том, что если один из этих ключей скомпрометирован, будет скомпрометирована только одна транзакция. С DUKPT исходящие (скажем, устройство ввода Pin-кода или PED) и принимающие (процессор, шлюз и т. д.) стороны имеют общий ключ. Этот ключ не используется для шифрования. Вместо этого для шифрования и дешифрования используется другой одноразовый ключ, производный от этого главного ключа данные. Важно отметить, что главный ключ не должен восстанавливаться из производного одноразового ключа. Чтобы расшифровать данные, получающая сторона должна знать, какой главный ключ использовался для создания одноразового ключа. Это означает, что принимающая сторона должна хранить и отслеживать мастер-ключ для каждого устройства. Это может быть много работы для тех, кто поддерживает много устройств. Для этого требуется более эффективный способ. Вот как это работает в реальной жизни: приемник имеет мастер ключ базовый ключ Деривации (BDK). BDK должен быть секретным и никогда не будет делиться ни с кем. Этот ключ используется для создания ключей, называемых начальным ключом шифрования Pin (IPEK). Из этого создается набор ключей, называемых будущими ключами, и IPEK отбрасывается. Каждый из будущих ключей встроен в PED производителем устройства, с которым они совместно используются. Этот дополнительный шаг деривации означает, что получателю не нужно отслеживать каждый ключ, который входит в PEDs. При необходимости их можно сгенерировать заново.

enter image description here

получатель разделяет будущие ключи с производителем PED, который вставляет по одному ключу в каждый PED. Если один из этих ключей скомпрометирован, PED можно повторно использовать с новым будущим ключом, производным от BDK, так как BDK по-прежнему безопасен.

шифрование и дешифрование

когда данные должны быть отправлены из PED в приемник, будущий ключ в этом устройство используется для создания одноразового ключа, а затем этот ключ используется с алгоритмом шифрования для шифрования данных. Эти данные затем отправляются в приемник вместе с серийным номером ключа (KSN), который состоит из идентификатора устройства и счетчика транзакций устройства. enter image description here

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

Source


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

require 'bundler/setup'
require 'test/unit'
require 'dukpt'

class DUKPT::DecrypterTest < Test::Unit::TestCase

      def test_decrypt_track_data
        bdk = "0123456789ABCDEFFEDCBA9876543210"
        ksn = "FFFF9876543210E00008"
        ciphertext = "C25C1D1197D31CAA87285D59A892047426D9182EC11353C051ADD6D0F072A6CB3436560B3071FC1FD11D9F7E74886742D9BEE0CFD1EA1064C213BB55278B2F12"
        plaintext = "%B5452300551227189^HOGAN/PAUL ^08043210000000725000000?\x00\x00\x00\x00"

        decrypter = DUKPT::Decrypter.new(bdk, "cbc")
        assert_equal plaintext, decrypter.decrypt(ciphertext, ksn)
      end
end

Теперь вы спрашиваете, как был создан "зашифрованный текст"...

Ну, первое, что мы знаем, это то, что он основан на "открытом тексте", который используется в коде, чтобы проверить, работает ли дешифрование.

открытый текст 0-padded-который соответствует шифрованию, которое тестируется путем проверки дешифрования с помощью этого DecrypterTest Тесткейса.

давайте посмотрим на кодировку...

Я нашел соответствующий код шифрования в https://github.com/Shopify/dukpt/blob/master/lib/dukpt/encryption.rb.

поскольку DecrypterTEst использует "cbc", становится очевидным, что шифрование использует:

 @cipher_type_des = "des-cbc"
 @cipher_type_tdes = "des-ede-cbc"

немного больше вниз, что код шифрования, следующее решает наш поиск ответа:

ciphertext = des_encrypt(...

, который показывает, что мы действительно смотрим на результат шифрование des.

Теперь DES имеет размер блока 64 бита. Это (64/8=) 8 байт двоичный, или - как "текст" порча-кодированное текстовое представление байт - 16 символов наговор.

на "текст" имеет длину 128 шестнадцатеричных символов, что означает, что он содержит (128 шестнадцатеричных символов/16 шестнадцатеричных символов=) 8 блоков DES с каждым 64 битами зашифрованной информации.

оборачивая все это в простой ответ:

когда глядя на "текст", вы смотрите на (8 блоков) зашифрованных данных DES, которые представляются с использованием читаемой человеком шестнадцатеричной (2 шестнадцатеричных символа = 1 байт) нотации вместо исходных двоичных байтов, которые будет производить шифрование DES.

Что касается шагов, связанных с "восстановление" зашифрованный текст, я склонен говорить вам просто использовать соответствующие части Рубин проект, на котором вы основывали свой вопрос. Просто должны посмотрите на исходный код. Файл на "https://github.com/Shopify/dukpt/blob/master/lib/dukpt/encryption.rb" в значительной степени объясняет все это, и я уверен, что все необходимые функции можно найти в репозитории GitHub проекта. Кроме того, вы можете попытаться воссоздать его самостоятельно - используя язык программирования по вашему выбору. Вам нужно только обрабатывать 2 вещи: шифрование/дешифрование DES и перевод bin-to-hex/hex-to-bin.


поскольку это одна из первых тем, которые возникают по этому поводу, я решил поделиться тем, как я смог кодировать зашифрованный текст. Это первый раз, когда я работал с Ruby, и это было специально для работы с DUKPT

сначала мне нужно было получить метод ipek и pek (такой же, как в decrypt). Затем распакуйте строку открытого текста. Преобразуйте распакованную строку в 72-байтовый массив (опять же, простите, если моя терминология неверна).

Я заметил в dukpt gem автора пример он использовал следующую строку простого текста

" %B5452300551227189^HOGAN / PAUL ^08043210000000725000000?\х00\х00\х00\х00"

Я чувствую, что эта строка неверна, так как после имени не должно быть пробела (AFAIK).. так и должно быть

" %B5452300551227189^HOGAN / PAUL^08043210000000725000000?\х00\х00\х00\х00"

в целом, это решение, на котором я оказался, может зашифровать строку, а затем расшифруйте его с помощью DUKPT

class Encrypt
include DUKPT::Encryption
attr_reader :bdk

def initialize(bdk, mode=nil)
  @bdk = bdk
  self.cipher_mode = mode.nil? ? 'cbc' : mode
end

def encrypt(plaintext, ksn)
  ipek = derive_IPEK(bdk, ksn)
  pek = derive_PEK(ipek, ksn)
  message =  plaintext.unpack("H*").first
  message = hex_string_from_unpacked(message, 72)
  encrypted_cryptogram = triple_des_encrypt(pek,message).upcase
  encrypted_cryptogram
end
def hex_string_from_unpacked val, bytes
  val.ljust(bytes * 2, "0")
end

конец

boomedukpt FFFF9876543210E00008 " %B5452300551227189^HOGAN / PAUL^08043210000000725000000?"

(мой рубиновый камень, KSN и строка простого текста)

2542353435323330303535313232373138395e484f47414e2f5041554c5e30383034333231303030303030303732353030303030303f000000000000000000000000000000000000

(мой рубиновый камень делает надевает распакованную строку после вызова hex_string_from_unpacked)

C25C1D1197D31CAA87285D59A892047426D9182EC11353C0B82D407291CED53DA14FB107DC0AAB9974DB6E5943735BFFE7D72062708FB389E65A38C444432A6421B7F7EDD559AF11

(мой рубиновый камень делает надевает зашифрованную строку)

%B5452300551227189^HOGAN / PAUL^08043210000000725000000?

(мой ruby gem делает puts после вызова decrypt на dukpt gem)


взгляните на это: https://github.com/sgbj/Dukpt.NET, я была в похожей ситуации, когда я задался вопросом, как реализовать dukpt на терминал, когда терминал имеет свои собственные вызовы функций, которые принимают init и КСН, чтобы создать первый ключ, так что моя единственная проблема была, чтобы убедиться, что метод init ключ был создан таким же образом, на терминале, как в упомянутой выше РЕПО код, который был достаточно простым, используя оссл библиотека для шифрования 3DES с EBC и применяя соответствующие фотошаблоны.