com.Utilities.PinBlock.java Source code

Java tutorial

Introduction

Here is the source code for com.Utilities.PinBlock.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.Utilities;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Security;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 *
 * @author ken
 */
public class PinBlock {

    public String pinProcess(String PIN, String PAN, String key) {

        try {
            Security.addProvider(new BouncyCastleProvider());

            //         String PIN = "1007";
            //        String PAN = "6396730416041961";
            //        String key = "26EA89DCA810CB8CBC19BA4C26C7943426EA89DCA810CB8C";
            //
            PinBlock p = new PinBlock();

            byte[] plain = p.processPinPan(PIN, PAN);

            byte[] keyBytes = HexString2Bytes(key);

            SecretKey keySpec = new SecretKeySpec(keyBytes, "DESede");

            IvParameterSpec iv = new IvParameterSpec(new byte[8]);

            Cipher e_cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding", "BC");

            e_cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);

            byte[] cipherText = e_cipher.doFinal(plain);
            //  System.out.println("Ciphertext: " + Bytes2HexString(cipherText).substring(0, 16));
            return Bytes2HexString(cipherText).substring(0, 16);
        } // end main
        catch (InvalidKeyException ex) {
            Logger.getLogger(PinBlock.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidAlgorithmParameterException ex) {
            Logger.getLogger(PinBlock.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalBlockSizeException ex) {
            Logger.getLogger(PinBlock.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BadPaddingException ex) {
            Logger.getLogger(PinBlock.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(PinBlock.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchProviderException ex) {
            Logger.getLogger(PinBlock.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchPaddingException ex) {
            Logger.getLogger(PinBlock.class.getName()).log(Level.SEVERE, null, ex);
        }

        return "";
    }

    public static void printHexString(String hint, byte[] b) {
        // System.out.print(hint);
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            //  System.out.print(hex.toUpperCase() + " ");
        }
        System.out.println("");
    }

    public static String Bytes2HexString(byte[] b) {
        String ret = "";
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase();
        }
        return ret;
    }

    public static byte uniteBytes(byte src0, byte src1) {
        byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 })).byteValue();
        _b0 = (byte) (_b0 << 4);
        byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 })).byteValue();
        byte ret = (byte) (_b0 ^ _b1);
        return ret;
    }

    // ken  24 bytes for tripleDES change to 8 for DES
    public static byte[] HexString2Bytes(String src) {

        byte[] ret = new byte[24];
        byte[] tmp = src.getBytes();
        for (int i = 0; i < 24; i++) {
            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
        }
        return ret;
    }

    public byte[] processPinPan(String pin, String pan) {

        byte arrPAN[] = getHexPAN(pan);
        byte arrPin[] = getHexPin(pin);
        byte arrRet[] = new byte[8];
        for (int i = 0; i < 8; i++) {
            arrRet[i] = (byte) (arrPin[i] ^ arrPAN[i]);
        }
        //    printHexString("Clear PIN Block", arrRet);
        return arrRet;
    }

    private byte[] getHexPin(String pin) {
        byte arrPin[] = pin.getBytes();
        byte encode[] = new byte[8];

        encode[0] = (byte) 0x04;
        encode[1] = (byte) uniteBytes(arrPin[0], arrPin[1]);
        encode[2] = (byte) uniteBytes(arrPin[2], arrPin[3]);
        encode[3] = (byte) 0xFF;
        encode[4] = (byte) 0xFF;
        encode[5] = (byte) 0xFF;
        encode[6] = (byte) 0xFF;
        encode[7] = (byte) 0xFF;
        printHexString("encoded pin", encode);
        return encode;
    }

    private byte[] getHexPAN(String pan) {

        int len = pan.length();
        byte arrTemp[] = pan.substring(len < 13 ? 0 : len - 13, len - 1).getBytes();
        byte arrAccno[] = new byte[12];
        for (int i = 0; i < 12; i++) {
            arrAccno[i] = (i <= arrTemp.length ? arrTemp[i] : (byte) 0x00);
        }
        byte encode[] = new byte[8];
        encode[0] = (byte) 0x00;
        encode[1] = (byte) 0x00;
        encode[2] = (byte) uniteBytes(arrAccno[0], arrAccno[1]);
        encode[3] = (byte) uniteBytes(arrAccno[2], arrAccno[3]);
        encode[4] = (byte) uniteBytes(arrAccno[4], arrAccno[5]);
        encode[5] = (byte) uniteBytes(arrAccno[6], arrAccno[7]);
        encode[6] = (byte) uniteBytes(arrAccno[8], arrAccno[9]);
        encode[7] = (byte) uniteBytes(arrAccno[10], arrAccno[11]);
        printHexString("encoded pan", encode);
        return encode;
    }
}