Skip to main content

· One min read
Alejandro Revilla

/by apr/ I work with Andy in several projects and I have to tell you, he's the most detail-oriented person I've ever met. He's the kind of guy that enjoy details, gets excited reading and writting specs and I don't know how, but he seems to memorize all of them. He is a voracious spec reader® that can pinpoint potential issues in specs from major institutions --that went through multiple internal revisions-- at first sight, and he writes amazingly detailed specs for even the simplest task. During development, when we ask for some piece of information, his invariable answer (even from Blackberry) is: 'look at page xxx of my spec' (we have a roadmap spec that includes pointers to all other involved specs, he calls that the 'master project workbook' where we can find literally everything related to a given project). Andy has a blog now, and interesting enough, his blog has an specs section that I'm sure readers of this blog will find very useful. I highly recommend that you add his feed to your agregator.

· 5 min read
Alejandro Revilla

/by apr/ Protecting Customer's Data

Many jPOS-EE users and PEP members have a recurring problem: encrypting sensitive data in order to protect their customers and if possible, make auditors happy.

But there's a recurring issue: unless you use an HSM, a smartcard to protect your keystore, or you have someone enter a pass-phrase at boot time, you have to live with the fear that someone could somehow access your keystore, get your master keys and decrypt your sensitive data.

The problem becomes more critical in situations where jPOS is installed at small merchants or medium-sized store chains, we can't ask them to enter a passphrase at boot time, we don't have smartcard readers there and we don't have HSMs.

We could do some security through obscurity but we leave that to our competitors :) Based on the work performed by Hani in the jPOS's security module, and the DUKPT implementation we did with Dave from InfoSecBlurb in a related project, I came up with a nice solution that I'd like to present here in order to get your feedback. Here is a simple example:

  SSM ssm = (SSM) NameRegistrar.get ("ssm");
SecureKeyStore ks = new SimpleKeyFile ("cfg/keys.cfg");
SecureDESKey bdk = (SecureDESKey) ks.getKey ("our-bdk");
String encrypted = ssm.customEncrypt (bdk, "4111111111111111=0805".getBytes());
String decrypted = new String (ssm.customDecrypt (bdk, encrypted), "ISO8859_1");

customEncrypt produces something like this:

B9B35297F48C792646CED3B367F40E6D,F302BA266FDAC3A6D4773B4C74553C49F584934BCA9224F8,5C9538880BED87FD

and customDecrypt gives you your original byte[] array back. Here is what we do:

  • We generate three clear-text 128-bit keys
  • We use the security module's console to enter those keys and produce a BDK encrypted under the local master keys (using standard key-ceremony procedures)
  • The BDK cryptogram is stored in the keys.cfg file
  • When we receive a message to encrypt, we generate two 64-bit random DES keys that we use as KSNs. We split them to produce a baseKeyID, deviceID and transactionCounter as required by KeySerialNumber
  • We use our BDK and these two KSNs to produce a pair of derived 64 bit keys
  • We combine these two 64 bit keys and do 3DES with them in order to encrypt our payload
  • We use both KSNs and derived keys plus the encrypted payload to produce an SHA hash, so we can perform sanity checks

So far, so good, it seems pretty nice, but it's still breakable if you have access to the master keys and the BDK's cryptograms, or, if you have access to the jar and you manage to call ssm.customDecrypt with the right parameters.

In order to mitigate that, I'm experimenting with several anti-debug features; besides obfuscating the jpos-ee jar (that's something that the PEP version already has), we are trying to have a hash of the stacktrace of the caller in order to validate the caller id and we have some timing control too.

But anyway, here is the best thing, a very simple one: we don't have to run this at every merchant, we can use this approach (or an HSM-based one) at a central location (such as an acquirer or transaction switch). When an acquirer or transaction switch receives say a 0200 message with a some sensitive data (i.e. PAN, EXP, TRACK1, TRACK2), it could reply with a 0210 carrying a cryptogram of that data computed at the remote facility, where we don't have access to the LMKs. We could do that with an extremely simple ISOFilter. Imagine something like this: Message sent from merchant to acquirer:

Message response from acquirer:

The acquirer's outgoing filter would build a custom cryptogram for us either using the aforementioned algorithm, an HSM on any other similar approach, and it would put it in a private field for us (in this case we used field 63, but could be any other free variable length private field) and an incoming filter at the acquirer would take care of decrypting it locally, unsetting that private field and setting the appropriate field 35 (same goes for other sensitive fields such as 2,14,45,52,55, etc.).

At the client application, you could store some clear-text information (such as BIN, last four digits of the PAN) for reporting purposes and store that opaque cryptogram produced by your acquirer/processor; that would be your ticket to request funds for that transaction if for some reason you need to perform a batch upload operation.

Although an scheme like this wouldn't solve problems like this, it would certainly help merchants protect its customers' data with a minor effort from the acquirers. The encrypted information could be an inner ISOMsg with just some sensitve field.

The document Secure Payment Framework presents some related concepts. I'd love to listen to potential flaws in this. I'd also like you to exchange some anti-debug ideas and links. So far, I'm serializing a Throwable's stacktrace, producing and validating a set of hashes with valid caller id info, an approach that is extremely sensible to JVM versions...

· 2 min read
Alejandro Revilla

/by apr/

For some time, my brother in law, who lives in Brasil, has been talking to me about his girlfriend's sister's husband (aka his brother in law) and the fact that he was a brilliant programmer, a genious! I went 'oh yeah... great' but honestly, I didn't pay too much attention.

Recently, he came to our place to spend with us Dec 31th, and he said that his girlfriend, along with her sister and husband (the brilliant programmer) were keen to come too, but they couldn't find a hotel (we were at a resort town, fully booked for the holiday season).

While I was cooking a BBQ , he went talking about how the guy has moved to the US, that he gives keynotes in many conferences, etc. etc. and after a few hours, he said, you might know him, his name is Miguel de Icaza.

What!?!?

I was shocked! I could have booked a hotel 6 months in advance, we could have hosted them at our place!

Damn, I missed this great oportunity to shake hands with a programmer of the caliber of Miguel! Lesson learnt, do not > /dev/null all what your in-law family members have to say ... :)

On the bright side, Miguel didn't have the chance to visit Punta del Este (a very nice city), but he saved himself a long rap about jPOS ... I have a Mono T-shirt now, sent by the author, and I expect him to get his jPOS T-shirt soon (on its way...) Small world, huh?

· 2 min read
Alejandro Revilla

/by apr/

If you use the jPOS' TransactionManager, and you use a Map to pass around your Context among participants, you may find yourself creating some kind of Contants kind of class in order to define your Context's keys. If you use jPOS-EE-SDK component model, you may find yourself creating a lot of those. distributed among different files, etc. and your code has to extend or implement many different interfaces in order to access them. I found a very simple solution. as part of jPOS-EE eecore module build, we search for *.k files and create a single org.jpos.ee.Constants file that you can rely to be there. So you write things like: Context.k


public static final String REQUEST = "REQUEST"
public static final String RESPONSE = "RESPONSE";
public static final String TERMINAL = "TERMINAL";
...
...

ErrorCode.k

  public static final String OK = "ok";
public static final String INVALID _ISSUER = "invalid.issuer";
public static final String INVALID_TERMINAL = "invalid.terminal";
...
...

that would create an interface org.jpos.ee.Constants like this:

package org.jpos.ee;
public interface Constants {
public static final String REQUEST = "REQUEST"
public static final String RESPONSE = "RESPONSE";
public static final String TERMINAL = "TERMINAL";
public static final String OK = "ok";
public static final String INVALID _ISSUER = "invalid.issuer";
public static final String INVALID_TERMINAL = "invalid.terminal";
}

We do the same with *.p files, we create a single org/jpos/ee/Constants.properties, so you can write something like this:

#
# defined in modules/mymodules/src/org/jpos/myapp/MyErrors.p
#
ok = 00 APPROVED
invalid.terminal = 14 INVALID TERMINAL
...
...

There's also a handy class called org.jpos.ee.K that implements Constants and give you access to the Constants.properties ResourceBundle by using code like this:

  String message = K.get (K.OK);  // would give you a "00 APPROVED"

PS.- Sorry to disappoint you... no fancy doclet processing here... this is just a very simple build patch that happens to do what I need. I hope you find it useful.

· One min read
Alejandro Revilla

/by apr/ An experimental prototype version of the long awaited ReplicatedSpace is out. You can read about it in jPOS-EE documentation (see Experimental chapter). We are very excited about the posibilities that components like this open to jPOS applications and we are looking forward to get your feedback and ideas about how to improve what we already have.

· One min read
Alejandro Revilla

/by apr/ jPOS Training/Montevideo is over, we managed to cover our schedule and even had some time to have some beers, wine, grappas and chivitos. We had the great honor to host world class developers - coming from North America, South Africa - traveling almost 30 hours to come to our training, we really appreciate that guys! We also had the chance to share some experiences and we got to know about some impressive products (such as kiosks, mobile payments, etc) that either rely or will rely on jPOS for exiting mission critical applications. jPOS TrainingjPOS TrainingjPOS TrainingjPOS TrainingjPOS Training We expect to come to a city near you the next time. Update: added trackback to Jeff's blog which has some beautiful panorama pictures of Montevideo.

· 2 min read
Alejandro Revilla

/by apr/ jPOS High Availability Service can be used to create a cluster of nodes where one of the nodes is used as a MASTER and the other(s) as SLAVE(S). A typical setup involves jPOS HA taking responsibility for standing-in with a virtual IP address in the cluster. In addition to providing peace of mind to your jPOS-EE installation, the HA Service has proven to be extremely useful when rolling out new software versions in a production environment, you roll it on a slave, then just disconnect the master, the slave becomes the new master running the new software. Should something go wrong, you re-connect the old master and disconnect the new one, that's something you can even do at the RJ45 patchbox level, which may be faster than typing commands under high pressure. jPOS-EE documentation has been updated and the jPOS-HA module is available for download . We have to thank Dave for his work in this module and for deploying it in several mission critical systems under his control. Dave is now enjoying a well deserved vacation in Europe, certainly confident that should something goes wrong with a master node, the slave will pick up the load ... he may be also crossing his fingers ... just in case ... Smiley

· One min read
Alejandro Revilla

/by apr/ We've made some minor changes to miniGL in order to integrate it as a jPOS-EE module. GLSession now have a few new constructors that accept a DB object, so we can reuse DB's Hibernate session. In addition miniGL's configuration has been adapted to jPOS-EE-SDK naming convention (see modules/minigl/cfg). This module depends on the following modules:

  • hibernate
  • hibernate_xxx
  • eecore