In my blog, I have a lot of posts about the Thales HSM 8000 and how we implemented an adapter for it in OLS.Switch, our jPOS-based payment system. In two recent posts, I discussed how to use jPOS' FSDMsg facility to implement the Thales command set, and a suggestion on how to start your integration efforts - by implementing the Thales Diagnostic command (the 'NC/ND') as Step One. I also have a post breaking down the command ('CI/CJ'), the one that does "Single DES BDK to Interchange Key Translation." [Make sure you read through the comments on that post, too.]
Recently, we were asked to augment our PIN Translation capabilities in order to support a population of PIN Pads that generate PIN blocks using either Single and Triple DES BDKs. I mentioned briefly in other posts that there's a separate command to do "Triple DES BDK to Interchange Key Translation" - the G0/G1. In this particular situation, the devices could only support double-length keys (Triple-length keys are an option when working with Triple DES BDKs), so our keys configuration file was going to have all double-length BDKs. We couldn't use cryptogram length to signal what's what to our program, so we needed some type of indicator. So, we came up with the idea of these '1des' and '3des' tags in the file to act as identifiers, like this (where '129908' and '184402' are examples of KSIs - the first six positions of the KSN in this particular implementation...read that Single DES BDK..." post referenced above for more details):
bdk.129908=1des:99BF6A880305B37775AE1E129676E421 bdk.184402=1des:80B7F397139F99A01266394CA96384D9
Then, we have our translatePinblk code in our adapter. We modified it to handle both key types and generate 'CI' or 'G0' commands (for Single or Triple DES BDK Translation respectively). Behind the scenes, what makes this code work is the jPOS FSDMsg facility. We've got the 'CI' and 'G0' structures defined, and that bolded line there fills in the key value (the 'command' field). You can see that the 'G0' has one extra field in its message format:
public FSDMsg translatePinblk (
String bdk, String zpk, String ksnDescriptor,
String ksn, String pinblk, String accountNumber)
{
boolean threeDesBdk = false;
if (bdk.startsWith ("3des:")) {
threeDesBdk = true;
bdk = bdk.substring(5);
} else if (bdk.startsWith ("1des:")) {
bdk = bdk.substring(5);
}
FSDMsg r = createRequest (threeDesBdk ? "G0" : "CI");
r.set ("bdk-type", "U");
r.set ("bdk", bdk);
r.set ("zpk-type", "U");
r.set ("zpk", zpk);
r.set ("ksn-descriptor", ksnDescriptor);
r.set ("ksn", ksn);
r.set ("pinblk", pinblk);
r.set ("destination-pinblk-format", "01"); // ANSI
r.set ("account-number", accountNumber);
if (threeDesBdk)
r.set ("source-pinblk-format", "01");
return command (r);
}
Now, here are some resulting traces ; I turned on tracing to the test HSM, so you can see all six legs (not presented in order, but you'll get the idea):
- Request from the device
- Request to the Thales (The Single DES example is first, followed by the Triple DES example).
- Response from the Thales
- Request to the Debit/EBT Gateway (the Translated PIN block goes into Field 52 on the outgoing message - the 'FFFFFF' in the middle is a mask applied for tracing purposes only).
- Response from the Debit/EBT Gateway
- Response to the device
<log realm="org.jpos.security.thales.ThalesAdapter" at="Tue Apr 24 16:09:45 EDT 2007.378">
<trace>
<fsdmsg schema='file:cfg/hsm-base'>
command: 'CI'
bdk: '3A796910699174AEEF512C5A489AB008'
zpk-type: 'U'
zpk: 'C6087BAD7B9827F553DDF858709E7030'
ksn-descriptor: '605'
ksn: '0407030000200016'
pinblk: '32D23493EC13C57F'
destination-pinblk-format: '01'
account-number: '777999999901'
</fsdmsg>
request: 'CI3A796910699174AEEF512C5A489AB008UC6087BAD7B9827F553DDF
858709E7030605040703000020001632D23493EC13C57F01777999999901'
response: 'CJ0004D354D87634C043FE01'
elapsed: 156ms
<fsdmsg schema='file:cfg/hsm-resp-base'>
response: 'CJ'
error: '00'
pin-length: '04'
pinblk: 'D354D87634C043FE'
</fsdmsg>
</trace>
</log>
<log realm="Debug" at="Tue Apr 24 16:09:45 EDT 2007.909">
<commit>
<id>9</id>
<context>
<transient>
<entry key="PROFILER">
<profiler>
open [0/0]
parse-request [0/0]
create-debit-tranlog [15/15]
populate-debit-tranlog [16/31]
validate-terminal [16/47]
find-duplicate [15/62]
translate-pin [172/234]
create-fdr-request [16/250]
query-host-or-reverse [453/703]
prepare-debit-response [0/703]
close [62/765]
send-response [0/765]
end [765/765]
</profiler>
</entry>
<entry key="DB">org.jpos.ee.DB@e47e9b</entry>
<entry key="REQUEST">
<fsdmsg schema='file:cfg/v2-base'>
header: '94538660'
record-format: 'G'
application-type: '0'
field-sep-1: '.'
acquirer-bin: '628702'
message-version: '02'
shift-number: '00006'
merchant-number: '0010'
store-number: '01856'
terminal-number: '0001'
category-code: '4444'
country-code: '987'
city-code: '97208'
timezone-differential: '010'
transaction-code: '93'
terminal-serial-number: '12345678'
encryption-indicator: '3'
transaction-sequence-number: '2480'
card-id-source: 'A'
account-entry-mode: 'D'
magnetic-strip-info: '401777______9011=_________________'
cid-device-attached: 'X'
pin-action-code: 'F'
pin-function-code: '0'
pin-length: '00'
pin-block: '00'
encrypted-pin-block: '32D234______C57F'
pin-dukpt-ksn: '040703______0016'
amount: '322'
additional-amount: '0'
register-number: '04'
tran-id: '0000276'
tender-attempt-indicator: '1'
tender-number: '0001'
tender-attempt: '0203'
</fsdmsg>
</entry>
<entry key="switch-key">G.93</entry>
<entry
key="TRANLOG">org.jpos.ee.DebitTranLog@1b98775[id=1987442]</entry>
<entry key="AUDIT">true</entry>
<entry key="MERCHANT">org.jpos.ee.Merchant@46e3f0[id=0010]</entry>
<entry key="TERMINAL">org.jpos.ee.Terminal@1b8be78[id=1]</entry>
<entry key="STORE">org.jpos.ee.Store@72ca69[id=01856]</entry>
<entry key="RESPONSE">
<fsdmsg schema='file:cfg/v2-debit-resp-base'>
header: '94538660'
record-format: '0'
terminal-serial-number: '12345678'
encryption-indicator: '3'
transaction-sequence-number: '2480'
magnetic-strip-info: '401777______9011=_________________'
register-number: '04'
tran-id: '0000276'
tender-attempt-indicator: '1'
tender-number: '0001'
tender-attempt: '0203'
response-code: 'AA'
display-message: 'APPROVAL'
approval-number: '210220'
date: '042407'
capture-date: '042407'
</fsdmsg>
</entry>
</transient>
<persistent>
<entry key="TIMESTAMP">Tue Apr 24 16:09:45 EDT 2007</entry>
<entry key="OUTSTANDING">0</entry>
<entry key="TRANLOG_ID">1987442</entry>
<entry key="CAPTURE_DATE">Tue Apr 24 00:00:00 EDT 2007</entry>
<entry key="ISO_REQUEST">
<isomsg direction="outgoing">
<field id="0" value="0200"/>
<field id="3" value="009000"/>
<field id="4" value="322"/>
<field id="7" value="0424200945"/>
<field id="11" value="003716"/>
<field id="12" value="160945"/>
<field id="13" value="0424"/>
<field id="18" value="5912"/>
<field id="22" value="901"/>
<field id="24" value="001"/>
<field id="25" value="00"/>
<field id="35" value="401777______9011=_________________"/>
<field id="37" value="711401856480"/>
<field id="41" value="00389999"/>
<field id="42" value="000452002888888"/>
<field id="49" value="840"/>
<field id="52" value="D354D8FFFFFF43FE" type="binary"/>
</isomsg>
</entry>
<entry key="ISO_RESPONSE">
<isomsg direction="incoming">
<field id="0" value="0210"/>
<field id="3" value="009000"/>
<field id="4" value="000000000322"/>
<field id="7" value="0424200945"/>
<field id="11" value="003716"/>
<field id="12" value="160945"/>
<field id="13" value="0424"/>
<field id="24" value="001"/>
<field id="25" value="00"/>
<field id="37" value="711401856480"/>
<field id="38" value="210220"/>
<field id="39" value="00"/>
<field id="41" value=" 00389999"/>
<field id="63" value="415050524F56414C2020202020202020" type="binary"/>
</isomsg>
</entry>
<entry key="RC">0000</entry>
</persistent>
</context>
</commit>
</log>
<log realm="org.jpos.security.thales.ThalesAdapter" at="Wed Apr 25 09:49:55 EDT 2007.56">
<trace>
<fsdmsg schema='file:cfg/hsm-base'>
command: 'G0'
bdk: 'D76FCCC0AB5F4A74875B39B9ADE6E900'
zpk-type: 'U'
zpk: 'B381A477B49A67C9581DFC81E9CA404C'
ksn-descriptor: '605'
ksn: '3D07040000000003'
pinblk: '661C4571C8A88998'
destination-pinblk-format: '01'
account-number: '765111111111'
source-pinblk-format: '01'
</fsdmsg>
request: 'G0D76FCCC0AB5F4A74875B39B9ADE6E900UB381A477B49A67C9581DFC81E9
CA404C6053D07040000000003661C4571C8A889980101765111111111'
response: 'G1000449FDE47BE6B24C1F01'
elapsed: 94ms
<fsdmsg schema='file:cfg/hsm-resp-base'>
response: 'G1'
error: '00'
pin-length: '04'
pinblk: '49FDE47BE6B24C1F'
</fsdmsg>
</trace>
</log>
<log realm="Debug" at="Wed Apr 25 09:49:55 EDT 2007.369">
<commit>
<id>12</id>
<context>
<transient>
<entry key="PROFILER">
<profiler>
open [0/0]
parse-request [0/0]
create-debit-tranlog [16/16]
populate-debit-tranlog [15/31]
validate-terminal [16/47]
find-duplicate [15/62]
translate-pin [94/156]
create-fdr-request [16/172]
query-host-or-reverse [281/453]
prepare-debit-response [0/453]
close [16/469]
send-response [0/469]
end [469/469]
</profiler>
</entry>
<entry key="DB">org.jpos.ee.DB@10457b4</entry>
<entry key="REQUEST">
<fsdmsg schema='file:cfg/v2-base'>
header: '3F0FD3C0'
record-format: 'G'
application-type: '0'
field-sep-1: '.'
acquirer-bin: '628702'
message-version: '02'
shift-number: '00006'
merchant-number: '0010'
store-number: '01856'
terminal-number: '0001'
category-code: '4444'
country-code: '987'
city-code: '97208'
timezone-differential: '010'
transaction-code: '93'
terminal-serial-number: '12345678'
encryption-indicator: '3'
transaction-sequence-number: '2500'
card-id-source: 'A'
account-entry-mode: 'D'
magnetic-strip-info: '421765______1119=____________________'
cid-device-attached: 'X'
pin-action-code: 'F'
pin-function-code: '0'
pin-length: '00'
pin-block: '00'
encrypted-pin-block: '661C45______8998'
pin-dukpt-ksn: '3D0704______0003'
amount: '2500'
additional-amount: '2000'
register-number: '04'
tran-id: '0000300'
tender-attempt-indicator: '1'
tender-number: '0003'
tender-attempt: '0203'
magnetic-strip-info-encrypted: 'kOGgk2__________________IsD+'
</fsdmsg>
</entry>
<entry key="switch-key">G.93</entry>
<entry
key="TRANLOG">org.jpos.ee.DebitTranLog@1fc68f[id=1987462]</entry>
<entry key="AUDIT">true</entry>
<entry key="MERCHANT">org.jpos.ee.Merchant@1cd36a5[id=0010]</entry>
<entry key="TERMINAL">org.jpos.ee.Terminal@1c914c3[id=1]</entry>
<entry key="STORE">org.jpos.ee.Store@2e0ecb[id=01856]</entry>
<entry key="RESPONSE">
<fsdmsg schema='file:cfg/v2-debit-resp-base'>
header: '3F0FD3C0'
record-format: '0'
terminal-serial-number: '12345678'
encryption-indicator: '3'
transaction-sequence-number: '2500'
magnetic-strip-info: '421765______1119=____________________'
register-number: '04'
tran-id: '0000300'
tender-attempt-indicator: '1'
tender-number: '0003'
tender-attempt: '0203'
response-code: 'AA'
display-message: 'APPROVAL'
approval-number: '312521'
date: '042507'
capture-date: '042507'
</fsdmsg>
</entry>
</transient>
<persistent>
<entry key="TIMESTAMP">Wed Apr 25 09:49:54 EDT 2007</entry>
<entry key="OUTSTANDING">0</entry>
<entry key="TRANLOG_ID">1987462</entry>
<entry key="CAPTURE_DATE">Wed Apr 25 00:00:00 EDT 2007</entry>
<entry key="ISO_REQUEST">
<isomsg direction="outgoing">
<field id="0" value="0200"/>
<field id="3" value="099000"/>
<field id="4" value="2500"/>
<field id="7" value="0425134954"/>
<field id="11" value="003730"/>
<field id="12" value="094954"/>
<field id="13" value="0425"/>
<field id="18" value="5912"/>
<field id="22" value="901"/>
<field id="24" value="001"/>
<field id="25" value="00"/>
<field id="35" value="421765______1119=____________________"/>
<field id="37" value="711501856500"/>
<field id="41" value=" 00389999"/>
<field id="42" value="000452002888888"/>
<field id="49" value="840"/>
<field id="52" value="49FDE4FFFFFF4C1F" type="binary"/>
<field id="54" value="2000"/>
</isomsg>
</entry>
<entry key="ISO_RESPONSE">
<isomsg direction="incoming">
<field id="0" value="0210"/>
<field id="3" value="099000"/>
<field id="4" value="000000002500"/>
<field id="7" value="0425135031"/>
<field id="11" value="003730"/>
<field id="12" value="094954"/>
<field id="13" value="0425"/>
<field id="24" value="001"/>
<field id="25" value="00"/>
<field id="37" value="711501856500"/>
<field id="38" value="312521"/>
<field id="39" value="00"/>
<field id="41" value=" 00389999"/>
<field id="63" value="415050524F56414C2020202020202020" type="binary"/>
</isomsg>
</entry>
<entry key="RC">0000</entry>
</persistent>
</context>
</commit>
</log>
Recent Comments