IBM 3624 Pin Offset Generation

I am working on creating pins with the IBM 3624 algorithm and then with its offset. Here is the algorithm from the IBM website :

I'm not sure about the order, the input needs to be used. For example, the algorithm requires validation data (Start Pos, Length, PAN Pad Character, and Pin Length), Ten-meter tables (0123456789012345), Pin, Pan, and PDK.

Edit: here is the input data format - PAN (account number or card number): 16-bit hex string. Pin (usually 4 digits, but can be changed as required): 4 digits digits (Hexadecimal values ​​to be replaced from the decimalization table) PDK (encrypted key supplied with PAN): 32 digit number

Start position and length: digits to be selected from PAN, the last digit is a check digit and will be ignored. These selected PAN digits are then padded to 16 digits.

Pad Char: single Char (hexadecimal digit).

And here is the code I'm using to do this:

public static void CalculatePINOffset(String PAN, String Pin, String PDKkey, String DecTab, int StartPos, int Length,
        char PadChar) throws Exception{
    int PANLength = PAN.length();
    if(Length != (PANLength - StartPos)){
        throw new Exception(
                "Invalid 'Start Pos and Length' format.");
    }
    //Padding the PAN before Start POS with Pad Chars back to 16 digits.
    String block = ISOUtil.padleft(PAN.substring(StartPos, Length + (StartPos - 1)), PAN.length(), PadChar);

    /*
     * Doing encryption stuff on block with PDKKey. 
     * The execute function basically encrypts block and PDKKey, and any algorithm could do the work. 
     */
    String result = execute(block , PDKkey, "2TDES");

    Map<Character, Character> decTab = new HashMap<Character, Character>();
    decTab.put('A', '0');
    decTab.put('B', '1');
    decTab.put('C', '2');
    decTab.put('D', '3');
    decTab.put('E', '4');
    decTab.put('F', '5');

    //Replacing Hex Characters with numbers from Decmalization table.
    char[] Inpin = result.substring(0, 4).toCharArray();
    for(int i = 0; i < Inpin.length; i++){
        if(decTab.containsKey(Inpin[i])){
            Inpin[i] = decTab.get(Inpin[i]);
        }
    }
    result = new String(Inpin);
    System.out.println("Intermediate PIN: "+result);

    //Calculating offset from Intermediate Pin.
    int[] Offset = new int[4];
    int Cpin;
    int Ipin;
    for(int i = 0; i < result.length(); i++){
        Ipin = Integer.parseInt(result.substring(i, i+1));
        Cpin = Integer.parseInt(Pin.substring(i, i+1));

        if((Cpin - Ipin) >= 0){
            Offset[i] = (Cpin - Ipin);
        }
        else{
            Offset[i] = (Ipin - Cpin)%10;
        }
    }

    String PinOffset = Arrays.toString(Offset);
    System.out.println("Pin Offset: " + PinOffset);
}

      

Note. I am not looking for code or implementation. I have provided this code snippet to better explain the usage. All that could help me is correct encryption order, use of validation data and decimal layout table.

When cross-checked using open source tools such as BP - Tools, the offset and output generated do not match. Where did I go wrong?

+3


source to share


2 answers


Ok I figured it out. If anyone is looking for the same, here's how to do it:

1. Generate validation data from PAN:
   - Get PAN Digits from Start Position to Length, and add Pad characters to the right, until it was 16 digits in length.
2. Encrypt validation data with pdk key using DES, 3DES or AES algorithm. This will generate an encrypted code.
3. Decimalize encrypted code using decimalization table.
4. Convert to Hex String, and get the first n digits (n = pin length). This will generate intermediate Pin.
5. Finally, Modulo Subtract intermediate pin with customer pin. This generates the Offset.

      



Hope this helps. - Thank!

+3


source


The problems are as follows:

  • Modulus subtraction is incorrect
  • Data validation starts with the rightmost digit before validating the digit.



public String calculateOffset(String pin, String pan, String pvk) throws Exception{
       System.out.println("CryptoProcessor.calculateOffset");
       Map decTab = Arrays.asList("0:0", "1:1", "2:2", "3:3", "4:4", "5:5","6:6", "7:7", "8:8", "9:9","A:0", "B:1", "C:2", "D:3", "E:4", "F:5")
           .stream()
           .map(elem -> elem.split(":"))
           .filter(elem -> elem.length==2)
           .collect(Collectors.toMap(e -> e[0], e -> e[1]));
       if(pan.length() = 0){
               Offset[i] = (Cpin - Ipin);
           }else{
               Offset[i] = (Cpin + 10 - Ipin);
           }
       }
       StringBuffer offset = new StringBuffer();
       IntStream.of(Offset).boxed().collect(Collectors.toList()).forEach(a -> offset.append(a.toString()));
       System.out.println("Pin offset: " + offset.toString());
       return offset.toString();
   }

Pan:1234567899876543
Pin:3196
pvk:0123456789ABCDEFFEDCBA9876543210
Validation data 456789987654FFFF
Jan 28, 2017 4:13:23 PM com.ocularminds.oswitch.crypto.CryptoProcessor process
INFO: Data : 456789987654FFFF
encrypted data 3DE7489FEBC9340D
Intermediate PIN: 3347
Pin offset: 0859

      

+1


source







All Articles