Re: [jpos-users] Encrypt PIN block with ZPK crypted Key using 3DES algorithm

2,441 views
Skip to first unread message
Message has been deleted

chhil

unread,
Sep 1, 2018, 11:35:17 PM9/1/18
to jpos-...@googlegroups.com
Cant do much to match your encrypted pinblock without knowing the pin encrypting clear in the clear.

To start off use the lmk keys provided by jpos so that we can be on the same page in terms of calculation.

Then create the terminal master key (TMK). (same key is should be inserted in the atm as the master key).
Then create the terminal pin keys (TPK) with the terminal master key as parent.

The key types should be TMK and TPK for ccreating the master and pin keys respectively

This pin key is either exchanged so that bot the atm and you share the same key.
Now the atm will send you the encrypted pin block.

We can work from there. 

Or you can generate the correct key types and do your calculations.

Your clear pin block generation is correct, that's the only thing I can verify for you at present.



 PIN blocks: PIN block encrypt operation finished
 ****************************************
 PAN:            4213683789082284
 PIN:            1234
 PAD:            N/A
 Format:        Format 0 (ISO-0)
 ----------------------------------------
 Clear PIN block:    0412027C876F7DD7
I use the freely available BP-tools from eftlab. 
image.png
 

-chhil
p.s.
Please do not sent direct emails. They will in possibility not get answered.



On Fri, Aug 31, 2018, 6:08 PM murali5999 <mural...@gmail.com> wrote:
Hi Team,

Could you please help me to solve the given ATM pinblock encryption in java code with JCESecurityModule.

Algorithm = 3DES.

I have created Pin Block with ATM Pin and Card Number.

For Example : PAN = 4213683789082284 PIN = 1234

 Result Pin Bock = 0412027C876F7DD7

Now I have to encrypt PINBlock with Crypt ZPK Key and Clear LMK Key.

ZPK Key in crypt form = 6E54DEB1561BB30FC36EC4895755D203
LMK Key = 9B204323F7460EF7EA58A4C1209DE01A9B204323F7460EFE

I will change LMK key in production scenario.

Result should be  encrypted PIN block = 3C214CC613862BD3

Thanks in Advance.


Krishna






--
--
jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage. Please support jPOS, contact: sa...@jpos.org
---
You received this message because you are subscribed to the Google Groups "jPOS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+...@googlegroups.com.
To post to this group, send email to jpos-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jpos-users/95a776a5-ebee-4c33-864d-4553aa403b62%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

chhil

unread,
Sep 3, 2018, 6:38:54 AM9/3/18
to jpos-...@googlegroups.com
Murali,

PLEASE DO NOT SEND DIRECT EMAILS to my inbox. POST questions in the user list. I will not respond to direct emails going forward.

If any of the keys/pins/pans are values from production, please make sure to get rid of them.

Due to your insecurely handling of pins/kets/pinblocks you wont be able to use the security module provided by jpos (or atleast  am not aware of).

You have provided the clear ZMK
You have provided the ZPK encrypted under the clear ZMK. 

What is shown below is 
  1. Decrypt the ZPK using the ZMK as key and get clear ZPK.
  2. Create a clear pin block using the JSecurityModule.
  3. Use the clear pinblock and clear zpk and create an encrypted pinblock.
  4. Is insecure and not PCI compliant. You are putting cardholders and your company at risk by doing this.

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import org.jpos.iso.ISOUtil;
import org.jpos.security.SMAdapter;
import org.jpos.security.SMException;
import org.jpos.security.jceadapter.JCESecurityModule;

public class Test {

    // Provided
    public static final String ZPK_ENCRYPTED_UNDER_ZMK = "C55863AF284988A96DE132E4F0BC9D6B";

    // Provided ZMK as 04645B680D4645E96E45AB4AABEC04D5, I have just split it
    // into 2 parts
    public static String       ZMK_PART1               = "04645B680D4645E9";
    public static String       ZMK_PART2               = "6E45AB4AABEC04D5";

    // Trick JCE by making a doblength key into a triple length, this way the
    // key doesnt change due to the way the key parts are encrypted and
    // decrypted fr 3DES
    public static final String ZMK                     = ZMK_PART1 + ZMK_PART2 + ZMK_PART1;

    public static void main(String[] args) throws SMException, NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {

        // this lmk file is from
        // https://github.com/jpos/jPOS/blob/master/jpos/src/test/resources/org/jpos/security/lmk-test
        JCESecurityModule sMod = new JCESecurityModule("c:/temp/delete/lmk.txt");

        // 4213683789082284 : Account number is last 12 excluding the check
        // digit = 368378908228
        byte[] clearPinblockFormat = sMod.calculatePINBlock("1234", SMAdapter.FORMAT00, "368378908228");
        System.out.println("Clear Pin Block :" + ISOUtil.hexString(clearPinblockFormat));

        // Decrypt the encryped ZPK using the clear ZMK
        SecretKeySpec zmk = new SecretKeySpec(ISOUtil.hex2byte(ZMK), "DESede");
        Cipher desCipher = Cipher.getInstance("DESede/ECB/NoPadding");
        desCipher.init(Cipher.DECRYPT_MODE, zmk);
        String clearZPK = ISOUtil.hexString(desCipher.doFinal(ISOUtil.hex2byte(ZPK_ENCRYPTED_UNDER_ZMK)));
        System.out.println("Clear ZPK:" + clearZPK);

        // Doing the same thing as we did for 3 part ZMK.
        String clearZPKtripleLength = clearZPK.substring(0, 16) + clearZPK.substring(16, 32)
                + clearZPK.substring(0, 16);
        // Encrypt the pinblock with the clear ZPK
        SecretKeySpec zpk = new SecretKeySpec(ISOUtil.hex2byte(clearZPKtripleLength), "DESede");
        desCipher.init(Cipher.ENCRYPT_MODE, zpk);
        String encryptedPinBlock = ISOUtil.hexString(desCipher.doFinal(clearPinblockFormat));
        System.out.println("Encrypted Pin Block :" + encryptedPinBlock);

    }
}

Output
Clear Pin Block :0412027C876F7DD7
Clear ZPK:67201CB0469D70A7F4F74ABAD01C793E
Encrypted Pin Block :3C214CC613862BD3


Additional info provided directly via email.
K
indly help me.I got strucked at encrypt pin block with ZPK and LMK keys. I am able to generate single ZMK key from 3 clear components of ZMK keys. Here Check values are matching. Next I am able to created ZPK key in crypt form from LMK and ZPK under ZMK key. . Here Check values are matching with ZPK given. Using ZPK and LMK I should able to generated encrypted Pin block from clear Pin block. At this point I strucked. ZMK Clear Components 1. 610B E543 3E61 C2C8 8CD9 CD02 83CD 86B9 2. 62EF 9D91 6E01 C770 D59D 610D A1A8 9D89 3. 0780 23BA 5D26 4051 3701 0745 8989 1FE5 ZMK Key check value: 01430B /********************************************************** ZMK Key from Clear Components 04645B680D4645E96E45AB4AABEC04D5;01430B LMK 3DES Key 9B204323F7460EF7EA58A4C1209DE01A9B204323F7460EFE ZPK Encrypted under ZMK C55863AF284988A96DE132E4F0BC9D6B Check Value : 84F640 ***********************************************************/ ZPK Key under ZMK: XC558 63AF 2849 88A9 6DE1 32E4 F0BC 9D6B ZPK Key check value: 84F640 PROCEDURE TO GENERATE THE ZPK WITH THE GIVEN ABOVE KEYS ******************************************************** Online-AUTH>fk Enter LMK id [0-1]: 0 Enter key length [1,2,3]: 2 Enter key type: 000 Enter key scheme: u Enter component type [X,H,T,E,S]: x Enter number of components [1-9]: 3 Enter component 1: <Put the above provided clear component 1> Enter component 2: <Put the above provided clear component 2> Enter component 3: <Put the above provided clear component 3> Encrypted key: <You will get the ZMK> Key check value: <ZMK check value - must match with the given above> Online-AUTH>ik Enter LMK id [0-1]: 0 Enter key type: 001 Enter key scheme: u Enter ZMK: <Put the ZMK key derived above> Enter ZMK variant: Enter key: <Put the ZPK encrypted under ZMK here> Encrypted key: <ZPK key> Key check value: <ZPK check value> ***************************************** Process Debit Card Number or PAN = 4213683789082284 PIN = 1234 LMK Key 9B204323F7460EF7EA58A4C1209DE01A9B204323F7460EFE ZPK Encrypted under ZMK C55863AF284988A96DE132E4F0BC9D6B 610BE5433E61C2C88CD9CD0283CD86B9;62EF9D916E01C770D59D610DA1A89D89;078023BA5D2640513701074589891FE5 ZMK Key from Clear Components 04645B680D4645E96E45AB4AABEC04D5;01430B ZPK Key in the encrypted form 6E54DEB1561BB30FC36EC4895755D203;84F640 3C214CC613862BD3 -- Resultant Encrypted Pin block( This value I need to pass in ISO message) 0412027C876F7DD7 --- Clear Pin block in hexadecimal 16 char generated from debitcard and PIN Thanks & Regards, Murali Krishna

chhil

unread,
Sep 3, 2018, 6:52:38 AM9/3/18
to jpos-...@googlegroups.com
The JCESecurityModule.calculatePINBlock is private, I made it public for the test code.
You need to copy/customize it.


private byte[] calculatePINBlock (String pin, byte pinBlockFormat, String accountNumber) throws SMException {  

Found at 

-chhi

chhil

unread,
Sep 3, 2018, 7:51:41 AM9/3/18
to jPOS Users

Hi,

Your question in https://groups.google.com/d/msg/jpos-users/KsDT_DAQwn8/nDzJIR8lBAAJ

What you attempted was correct (except the account number needed the check digit to be stripped).

Given the ZMK components (from this thread) I form the key. 
-lmk c:\temp\delete\lmk.txt FK 128 ZMK 610BE5433E61C2C88CD9CD0283CD86B9 62EF9D916E01C770D59D610DA1A89D89 078023BA5D2640513701074589891FE5
078023BA5D2640513701074589891FE5
Output 
<log realm="jce-security-module" at="2018-09-03T11:42:56.499" lifespan="1ms">
  <local-master-keys>
    Loaded successfully from file: "C:\Temp\delete\lmk.txt"
  </local-master-keys>
</log>
<log realm="jce-security-module" at="2018-09-03T11:43:00.075" lifespan="3575ms">
  <s-m-operation>
    <command name="Form Key from Three Clear Components">
      <parameter name="Key Length">
        128
      </parameter>
      <parameter name="Key Type">
        ZMK
      </parameter>
      <parameter name="Component 1 Check Value">
        25777E
      </parameter>
      <parameter name="Component 2 Check Value">
        125887
      </parameter>
      <parameter name="Component 3 Check Value">
        1A9879
      </parameter>
    </command>
    <result name="Formed Key">
      <secure-des-key length="128" type="ZMK" variant="0" scheme="X">
        <data>1684CF19B350B76809D326F251C7F465</data>
        <check-value>01430B</check-value>
      </secure-des-key>
    </result>
  </s-m-operation>
</log>
ZMK encrypted under LMK is 1684CF19B350B76809D326F251C7F465


Then I ran the console command to import the encrypted ZPK and the ZMK.
-lmk c:\temp\delete\lmk.txt IK 128 ZPK C55863AF284988A96DE132E4F0BC9D6B 128 ZMK 1684CF19B350B76809D326F251C7F465 01430B

Output 
<log realm="jce-security-module" at="2018-09-03T16:59:42.757" lifespan="539ms">
  <s-m-operation>
    <command name="Import Key">
      <parameter name="Key Length">
        128
      </parameter>
      <parameter name="Key Type">
        ZPK
      </parameter>
      <parameter name="Encrypted Key">
        C55863AF284988A96DE132E4F0BC9D6B
      </parameter>
      <parameter name="Key-Encrypting Key">
        <secure-des-key length="128" type="ZMK" variant="0" scheme="X">
          <data>1684CF19B350B76809D326F251C7F465</data>
          <check-value>01430B</check-value>
        </secure-des-key>
      </parameter>
      <parameter name="Check Parity">
        true
      </parameter>
    </command>
    <result name="Imported Key">
      <secure-des-key length="128" type="ZPK" variant="0" scheme="X">
        <data>FA2B81880CEC3B3623A7538BB54C2E36</data>
        <check-value>84F640</check-value>
      </secure-des-key>
    </result>
  </s-m-operation>
</log>
Imported ZPK is FA2B81880CEC3B3623A7538BB54C2E36


Now I used your code from the link provided at the top and used the ZPK and check value from the the console generated ones and the pan used in this thread. Please note the ZPK files are local to you the difference in values will result in different cryptograms but the check values (which are for the clear keys will always be the same) which means if I have lmk file 1 and you have lmk file 2, the cryptograms for keys would be different but the check digits for the keys will be the same.

If we both have a clear key KEY1 and use our HSMS which have different LMKs . My hsm will use key1 encrypt it with an LMK1 and give me cryptogram1, similarly your hsm will use its LMK1 and generate a cryptogram2. The check digits generated by both hsms will be the same as check digits are obtained using the clear key Key1 encrypting with 0's. But when I pass it cryptogram1 it will decrypt it with my lmk1 to get the same key1 and if if you pass crypogram2, your hsm will use your lmk1 to decrypt it and give back keys1. So LMK values should not be a concern.


import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.jpos.iso.ISOUtil;
import org.jpos.security.EncryptedPIN;
import org.jpos.security.SMAdapter;
import org.jpos.security.SMException;
import org.jpos.security.SecureDESKey;
import org.jpos.security.jceadapter.JCESecurityModule;

public class Test 
{

    
public static void main(String[] args) throws SMException, NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException 
{

        jposWay();

    }

    protected static void jposWay() throws SMException {
        JCESecurityModule jcesecmod = new JCESecurityModule("c:/temp/delete/lmk.txt", "com.sun.crypto.provider.SunJCE");
        String pin = "1234";
        System.out.println("PIN ==>> " + pin);
        String pan = "368378908228";// (Original Pan number 4593511985236238, I
                                    // have used right most 12 digit)
        System.out.println("PAN ==>> " + pan);
        String zpkKey = "FA2B81880CEC3B3623A7538BB54C2E36"; // here goes the
                                                            // secure-des-key
        // gerated in the previous step
        System.out.println("ZPK KEY ==>> " + zpkKey);
        SecureDESKey sdk = new SecureDESKey(SMAdapter.LENGTH_DES3_2KEY, SMAdapter.TYPE_ZPK, zpkKey, "84F640");
        EncryptedPIN pinUnderLMK = jcesecmod.encryptPINImpl(pin, pan);
        System.out.println("pinUnderLMK ==>>" + ISOUtil.hexString(pinUnderLMK.getPINBlock()));
        EncryptedPIN pinUnderZPK = jcesecmod.exportPINImpl(pinUnderLMK, sdk, SMAdapter.FORMAT00);
        System.out.println("pinUnderZPK ==>>" + ISOUtil.hexString(pinUnderZPK.getPINBlock()));
    }

}

Output

PIN ==>> 1234
PAN ==>> 368378908228
ZPK KEY ==>> FA2B81880CEC3B3623A7538BB54C2E36
pinUnderLMK ==>>A0AC2E5AC183CB87
pinUnderZPK ==>>3C214CC613862BD3
-chhil
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+unsubscribe@googlegroups.com.

murali5999

unread,
Sep 3, 2018, 12:53:12 PM9/3/18
to jPOS Users
Dear Chhil,

Thanks you so much for your kind help. The above is test data only. I have not seen this kind of support from any forum till now. 

I am very thankful to Chhil and other forum members who are continuously supporting.

I will contribute my skill set to this forum and help to others.

Thanks Chhill. You are Awesome.


Murali.

Andy Orrock

unread,
Sep 3, 2018, 1:10:58 PM9/3/18
to jpos-...@googlegroups.com
I could not agree more about your opinion of Chhil.  He goes above and beyond to help people.  It is the nature of his character.

Andy

--
--
jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage. Please support jPOS, contact: sa...@jpos.org
---
You received this message because you are subscribed to the Google Groups "jPOS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+...@googlegroups.com.

To post to this group, send email to jpos-...@googlegroups.com.

Luiz Felipph

unread,
Sep 3, 2018, 1:30:38 PM9/3/18
to jpos-...@googlegroups.com

chhil

unread,
Sep 3, 2018, 10:51:34 PM9/3/18
to jpos-...@googlegroups.com
Thank you for the kind words. 
I have having been there and continue to be there requiring support from the wonderful people here, it only makes sense
giving back to this jpos family.
Andy, its only been 6 years since I wrote my first line of code for jpos under your guidance, thank you.

-chhil
 

Reply all
Reply to author
Forward
0 new messages