Java-реализация 3DES и DUKPT для расшифровки данных устройства чтения кредитных карт с помощью эмуляции клавиатуры?
У нас есть интерактивный интерфейс для ввода ключей, и мы поддерживаем возможность считывания с кредитных карт. В современной отрасли считыватель карт должен зашифровать информацию перед ее кодированием в ASCII, а затем расшифровать ее на стороне сервера. (поэтому локальный компьютер никогда не видит информацию о карте)
Я использую устройство считывания карт MagTek в режиме эмуляции клавиатуры, и мне вводят стандартную клавишу ANSI для тестирования. После успешного декодирования и расшифровки мы зарегистрируем наш собственный ключ в MagTek и закажем некоторые считыватели для промышленного использования.
Я знаю, что эта расшифровка была реализована ранее в C# и других языках, но нужно что-то в Java или, возможно, в какой-нибудь другой CLI-доступной программе, которая может быть включена в веб-приложение Java. Я собираюсь приступить к переносу некоторого кода C# на Java, но сначала нужно настроить среду C#. (Я никогда не делал этого раньше.)
Убедившись, что версия C# работает хорошо, я знаю, что могу устранить любые ошибки во время переноса с помощью моих обычных методов отладки.
Прежде чем пройти через все это, пожалуйста, дайте мне знать, если есть более простой способ. Я думаю, что это уже было сделано на Java, но, возможно, нет...
1 ответ
Частичный ответ, CW для любого, чтобы добавить.
Во-первых, неясно (для меня), хотите ли вы запускать на ПК или чем-то подобном, где устройства смахивания, возможно, загружены (например, апплет или веб-запуск), или просто получить зашифрованные данные смахивания (в веб-форме?) И отправить их. на ваш сервер для расшифровки. Я полагаю, что последнее облегчает соответствие PCI DSS.
Java crypto, безусловно, делает 3DES под именем DESede (без учета регистра, как и все имена JCA Cipher). Немного неочевидный момент: реализация в SunJCE обрабатывает только полные 24-байтовые ключи. DUKPT использует "2-клавишную 3DES", поэтому вам нужно скопировать "left" в байты 0-7, "right" в 8-15 и "left" снова в 16-23. Если вы используете BouncyCastle (как это делает мой магазин), он может взять 16-байтовый ключ и сделать копию внутри, что немного удобнее. (Симметричный ключ в Java - это байтовый массив в классе тонкой оболочки, обычно javax.crypto.spec.SecretKeySpec
.)
Если вы не знакомы с Java-шифрованием в целом, вы можете получить "экземпляр" определенного алгоритма или режима у "провайдера" (вы можете указать один или позволить Java выбирать автоматически; несколько встроены, а другие могут быть добавлен, как "bcprov" из www.BouncyCastle.org) с использованием универсального класса API Cipher
, Signature
, MessageDigest
и т. д., затем инициализируйте этот экземпляр с необходимыми параметрами (такими как ключ или IV и направление), затем вызовите методы для получения входных данных и возврата вывода либо в виде отдельных (возможно, нескольких) шагов, либо в виде простого комбинированного doFinal
(что хорошо для вашего случая). Руководство JCA http://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html и javadoc для применимого класса API javax.crypto.Cipher
(на http://docs.oracle.com/javase/8/docs/api/index.html а также автоматически отображается в ведущих IDE) достаточно подробно об этом.
Я не видел открытой / бесплатной реализации DUKPT, но это не доказывает, что ее нет. Это просто, хотя и немного утомительно, просто кодировать шаги из X9.24, если никто не предлагает лучше.