MENU

 

 

 

 

Documentation

  1. Installation
  2. Core Components
  3. Usage
    1. Normal Usage
    2. HThalesMSg XML definition
  4. Q2/JPOSEE Usage
  5. PCI Compliance
  6. Adaptation for QMUX
  7. Throughput and Multiple Connections

1. Installation

You can download the precompiled JAR file or the source file,

If you don't wanna go to the trouble of compiling it, just copy

HThales.jar somewhere in your classpath directory.

For Q2/JPOS-EE usage I Think on most of the cases you need to copy the jar file into the lib directory inside the deploy folder(the one where all your Q2 bean xml definition resides.

UPDATE : JPOS Q2 uses a seperate classloader for loading jars in deploy/lib directory.

Unfortunately, my HThalesAdaptor.class uses instanceof Operator, so it won't work for Q2 unless you compile the source along with the JPOS module and its all in one jpos-ee.jar

 

And don't forget to copy your Message Definition XML files, to a directory somewhere.

2. Core Components

HThalesMsg

This is the FSDMsg style Thales Racal command parser, with a few added field type and seperator compared to the original FSDMsg, they are

Field Type : T

Represents a Thales KeyScheme+Key

Length : 16H, 1A+16H/32H/48H

Supports the keySchemes

the field type T will set lenght to the default lenght specified in the schema definition, until it recieves a keyscheme that overrides it.

So practically speaking for ZMK keys you use field definitions like

<field id='zmk' type='T' length='16'/>

When theres no prefix in front, it assumes a 8 byte, 16 HEXCHAR key

With specific prefix U,T,X,Y it will automatically select the correct lenght.

And this is for CVK, since the default is usually 32
<field id='cvk' type='T' length='32'/>

 

PS, Adding additional keyscheme for EMV and etc is trivial if you're willing to look at the source

 

 

Field Type O

For optional data, that may or may not be present, usually used in conjuction with pre separators

 

Seperator ES

Gives you a semicolon ';' as a separator

 

PreSeparators

Just like a separator, but their placed at the start of the field, usually used with optional data.

PreSeparator SS = ';'

PreSeparator SP = '%'

PreSeparator SC = 'X'19'

 

 

 

 

HThalesCore

Reponsible for creating the request, by looking up the schema definition files in the specified directory and creating connection

 

HThalesAdaptor

A Q2ChannelAdaptor like component that if you use a JPOS Q2 architecture will take care of keeping the connection alive and uses Java Spaces.

 

 

 

 

3. Usage

For normal usage, use code like

import net.hairi.Thales.*;

....................

 

//Function parameters String hostname, int port, String basepath, String schema

//basepath is where you store all your HThalesMsg schema xml definition file

HThalesCore core = new HThalesCore("localhost", 1234,"cfg/hsm-", "base");

 

HThalesMsg req = core.generateDoubleLengthKey();

try {

       core.connect();

         HThalesMsg rep = core.comand(req);

} catch (Exception e) { .. }

 

I've implemented some HSM commands in the HThalesCore as a reference guide, when you're creating your own commands with definition files your code will probably look like

Thales JC message for PINBLOCK

.........................

HThalesMsg req3 = core.createRequest("JC");

req3.set("source-tpk", "U8463435FC4B4DAA0C49025272C29B12C");
req3.set("pin-block", "028DCC093FB0471F");
req3.set("pin-block-format", "03");
req3.set("account-number", "407000025321");

try {

         HThalesMsg rep = core.command(req);

} catch (Exception e) { .. }

 

With message definition like

File : hsm-JC.xml

<?xml version='1.0' encoding='UTF-8'?>
<schema id='JC'>
<field id='source-tpk' type='T' length='32'/>
<field id='pin-block' type='A' length='16'/>
<field id='pin-block-format' type='A' length='2'/>
<field id='account-number' type='A' length='12'/>
</schema>

 

And the corresponding response definition

File : hsm-resp-JD.xml

<?xml version='1.0' encoding='UTF-8'?>
<schema id='JD'>
<field id='PIN' type='A' length='5'/>
</schema>

So .....

When you need to implement a new command, just prepare the FSD defintion file.

Here is another example that makes use of the optional data field and preseparators

File : hsm-DW.xml

<?xml version='1.0' encoding='UTF-8'?>
<schema id='DW'>
<field id='zmk' type='T' length='32'/>
<field id='cvk' type='T' length='32'/>
<field id='optiondata' type='OSS' length='3'/>
<field id='trailerdata' type='OSC' length='10'/>
</schema>

 

File : hsm-DX.xml

<?xml version='1.0' encoding='UTF-8'?>
<schema id='DX'>
<field id='bdk' type='T' length='32'/>
<field id='kcv' type='AEOF' length='12'/>
</schema>

With code like

......................

HThalesMsg req = core.createRequest("DW");

req.set("zmk", "U1457FF6ADF6250C66C368416B4C9D383");
req.set("cvk", "6A2C67C227784BC5D8508B6BED82ECB8");
req.set("optiondata","0U1");
req.set("trailerdata","1234567890");

try {

         core.connect();

          HThalesMsg rep = core.command(req);

} catch (Exception e) { .. }

 

 

Thread Safety and Concurency

Unlike ISO8583 switching host that sometimes route messages to other far flung host, and messages response can arrive in different order;

I'm pretty sure that Thales HSM RG series process incoming messages synchroniously FIFO(First In First Out),

Just add a synchronized keyword/block in your code, and it should be fine.

 

Variable Length Field

When dealing with variable lenght fields, just browse the schema definition example so that you can implement the proper one for your needs.

 

 

 

4. Q2/JPOS EE Usage

For Q2 we have the HThalesAdaptor Q2 Bean, with xml deployment like this

<?xml version="1.0" ?>

<HThales-adaptor name='thales-adaptor'
class="net.hairi.Thales.HThalesAdaptor" logger="Q2">
<host>hsmhostt</host>
<port>9998</port>
<keep-alive>yes</keep-alive>
<keep-alive-interval>10000</keep-alive-interval>

<basepath>cfg/hsm-</basepath>
<in>hthales-send</in>
<out>hthales-receive</out>
<reconnect-delay>10000</reconnect-delay>
</HThales-adaptor>

You cand send message like

 

Space sp = SpaceFactory.getSpace();

HThalesMsg req4 = core.createRequest("DG");

req4.set("pvk-pair", "UA8B1520E201412938388191885FFA50A");
req4.set("pin", "01234");
req4.set("account-number", "407000025321");
req4.set("pvki", "1");

sp.out("hthales-send", req4);

HThalesMsg resp4 = sp.in("hthales-receive", 10000);


Or to ensure thread safety wrap it under TSpace

Space sp = SpaceFactory.getSpace();

TSpace ts = new TSpace();

HThalesMsg req4 = core.createRequest("DG");

req4.set("pvk-pair", "UA8B1520E201412938388191885FFA50A");
req4.set("pin", "01234");
req4.set("account-number", "407000025321");
req4.set("pvki", "1");

ts.out ("Request", req4);

sp.out("hthales-send", ts);

HThalesMsg resp = ts.in ("Response", 10000);


The HThalesAdaptor accepts both FSDMsg and TSpace input into its in space.

JMX is supported, so you can manage it via the JMX console for some cool stuff.

5. PCI Compliance

I think HThalesAdaptor should be PCI compliant.

The thing is, last time I checked TSpace and JPOS default space implementation doesn't serialize to disk. I don't know if that has changed.

Why does this matter ?, because PCI forbid any sensitive info stored in permanant media.

If it does, you need to wrap your request to other Java space implementation

6. QMUX and Thales Racal Message Trailer

No, you can't currently wrap HThalesAdaptor in a Qmux, I don't see any hard requirements for it. However since a few of you in JPOS mailing list insist on using it, my tip is, just recast FSDMsg to FSDISOMsg, and send it over the wire.

Add FSDISOMsg handling to HThales adaptor space input, and don't forget

in your FSD XML definition every last field should use the FS type, so that JPOS will ad 1C after it, after that add in the field "11" and "41" which the QMux uses.

7. Throughput

Right, to get the max rated troughput on your Thales HSM you usually need to have multiple connections.

Luckily Java Space and JPOS Q2 provides a very straightforward way to do this.

Create 2 deployment descriptor for HThalesAdaptor with different name attribute, referencing to the same in/out space

 

<?xml version="1.0" ?>

<HThales-adaptor name='thales-adaptor1'
class="net.hairi.Thales.HThalesAdaptor" logger="Q2">
<host>hsmhostt</host>
<port>9998</port>
<keep-alive>yes</keep-alive>
<keep-alive-interval>10000</keep-alive-interval>

<basepath>cfg/hsm-</basepath>
<in>hthales-send</in>
<out>hthales-receive</out>
<reconnect-delay>10000</reconnect-delay>
</HThales-adaptor>

 

<?xml version="1.0" ?>

<HThales-adaptor name='thales-adaptor2'
class="net.hairi.Thales.HThalesAdaptor" logger="Q2">
<host>hsmhostt</host>
<port>9998</port>
<keep-alive>yes</keep-alive>
<keep-alive-interval>10000</keep-alive-interval>

<basepath>cfg/hsm-</basepath>
<in>hthales-send</in>
<out>hthales-receive</out>
<reconnect-delay>10000</reconnect-delay>
</HThales-adaptor>

And just send it through space.

 

Space sp = SpaceFactory.getSpace();

TSpace ts = new TSpace();

HThalesMsg req4 = core.createRequest("DG");

req4.set("pvk-pair", "UA8B1520E201412938388191885FFA50A");
req4.set("pin", "01234");
req4.set("account-number", "407000025321");
req4.set("pvki", "1");

ts.out ("Request", req4);

sp.out("hthales-send", ts);

HThalesMsg resp = ts.in ("Response", 10000);


Problem solved.

The Space will do the balancing automatically for you.