We have an online key-in interface, and are support credit card swipe capability. In the industry today, the card reader should encrypt the information before encoding it to ASCII, and then it is up to server-side to decrypt. (so the local machine never sees the card info)
I am using MagTek card reader in keyboard emulation mode, and have it with the ANSI standard key injected for testing purposes. Once decode & decryption successful, we'll get our own key registered with MagTek and order some production-use readers.
I know this decryption has been implemented before in C# and other languages, but need something in Java, or perhaps some other CLI-accessible program that can be included with a Java webapp. I am about to proceed with porting some C# code to Java, but first need to set up a C# environment. (I've never done this before.)
Once I've ensured the C# version works well, then I know I can eliminate any errors during porting with my usual debugging techniques.
Before I go through all of this, if there is an easier way please let me know. I would think this has already been done in Java, but perhaps not...
Partial answer, CW for anyone to add to.
First, it's not clear (to me) if you want to run on PCs or similar where the swipe devices are, possibly downloaded (like applet or webstart), or to just get the encrypted swipe data (in a webform?) and send it to your server to decrypt. I suggest the latter makes PCI DSS compliance easier.
Java crypto certainly does 3DES, under the name DESede (case-insensitive, like all JCA Cipher names). One slightly unobvious point: the implementation in SunJCE only handles full 24-byte keys. DUKPT uses "2-key 3DES", so you need to copy "left" to bytes 0-7, "right" to 8-15, and "left" again to 16-23. If you use BouncyCastle (as my shop does) it can take a 16-byte key and do the copy internally, which is slightly more convenient. (A symmetric key in Java is a byte array in a thin wrapper class, usually javax.crypto.spec.SecretKeySpec
.)
If you're not familiar with Java crypto in general, the pattern is that you obtain an "instance" of a particular algorithm or mode from a "provider" (you can specify one or let Java choose automatically; several are builtin and more can be added, like "bcprov" from www.BouncyCastle.org) using a generic API class Cipher
, Signature
, MessageDigest
, etc, then initialize that instance with needed parameters (such as key or IV, and direction), then call methods to take input data and return output either in separate (possibly multiple) steps or in a simple combined doFinal
(which is fine for your case). The JCA manual http://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#Cipher and javadoc for the applicable API class javax.crypto.Cipher
(at http://docs.oracle.com/javase/8/docs/api/index.html and also automatically displayed in leading IDEs) has quite full details on this.
I haven't seen any open/free implementation of DUKPT but that doesn't prove there isn't one. It is straightforward, though a bit tedious, to just code the steps from X9.24, if no one offers better.