org.jpos.security.EncryptedPIN Maven / Gradle / Ivy
Show all versions of jpos Show documentation
/*
* jPOS Project [http://jpos.org]
* Copyright (C) 2000-2015 Alejandro P. Revilla
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package org.jpos.security;
import org.jpos.iso.ISOUtil;
import org.jpos.util.Loggeable;
import org.jpos.iso.ISOException;
import java.io.PrintStream;
import java.io.Serializable;
import java.security.InvalidParameterException;
/**
*
* The PIN (Personal Identification Number), is used to authenticate card
* holders. A user enters his/her PIN on the pin-pad (also called pin entry device)
* of a terminal (whether ATM or POS). The terminal forms the PIN Block, which
* is a mix of the PIN and the account number.
* In a typical environment, the PIN Block (not the PIN) gets encrypted and sent
* to the acquirer. This Encrypted PIN Block is the typical content of the
* PIN Data ISO Field (Field 52).
* This class represents an encrypted PIN, no matter by whom it is encrypted.
* Typically a PIN is encrypted under one of these three:
* 1- Under a terminal PIN key (like TPK or DUKPT)
* 2- Under an Interchange PIN key (like ZPK)
* 3- Under the the security module itself (i.e. under LMK)
* This class knows nothing about, who encrypted it.
*
*
* This class represents an encrypted PIN using:
* 1- The PIN Block (encrypted)
* 2- The account number (the 12 right-most digits of the account number excluding the check digit)
* 3- The PIN Block Format
*
*
* The PIN Block Format specifies how the clear pin (as entered by the card holder)
* and the account number get mixed to form the PIN Block.
*
* @author Hani Samuel Kirollos
* @version $Revision$ $Date$
* @see SMAdapter
*/
public class EncryptedPIN
implements Serializable, Loggeable {
private static final long serialVersionUID = -9117335317030664867L;
/**
* Account Number (the 12 right-most digits of the account number excluding the check digit)
*/
String accountNumber;
/**
* This is the ByteArray holding the PIN Block
* The PIN Block can be either clear or encrypted
* It is typically DES or 3DES encrypted, with length 8 bytes.
*/
byte[] pinBlock;
/**
* The PIN Block Format
* value -1 means no block format defined
*/
byte pinBlockFormat;
public EncryptedPIN () {
super();
}
/**
*
* @param pinBlock
* @param pinBlockFormat
* @param accountNumber account number, including BIN and the check digit
*/
public EncryptedPIN (byte[] pinBlock, byte pinBlockFormat, String accountNumber) {
setPINBlock(pinBlock);
setPINBlockFormat(pinBlockFormat);
setAccountNumber(extractAccountNumberPart(accountNumber));
}
/**
* @param pinBlock
* @param pinBlockFormat
* @param accountNumber if extract
is false then account number, including BIN and the check digit
* or if parameter extract
is true then 12 right-most digits of the account number, excluding the check digit
* @param extract true to extract 12 right-most digits off the account number
*/
public EncryptedPIN (byte[] pinBlock, byte pinBlockFormat, String accountNumber, boolean extract) {
setPINBlock(pinBlock);
setPINBlockFormat(pinBlockFormat);
setAccountNumber(extract ? extractAccountNumberPart(accountNumber) : accountNumber);
}
/**
* @param pinBlockHexString the PIN Block represented as a HexString instead of a byte[]
* @param pinBlockFormat
* @param accountNumber account number, including BIN and the check digit
*/
public EncryptedPIN (String pinBlockHexString, byte pinBlockFormat, String accountNumber) {
this(ISOUtil.hex2byte(pinBlockHexString), pinBlockFormat, accountNumber);
}
/**
* @param pinBlockHexString the PIN Block represented as a HexString instead of a byte[]
* @param pinBlockFormat
* @param accountNumber if extract
is false then account number, including BIN and the check digit
* or if parameter extract
is true then 12 right-most digits of the account number, excluding the check digit
* @param extract true to extract 12 right-most digits off the account number
*/
public EncryptedPIN (String pinBlockHexString, byte pinBlockFormat, String accountNumber, boolean extract) {
this(ISOUtil.hex2byte(pinBlockHexString), pinBlockFormat, accountNumber, extract);
}
/**
* dumps PIN basic information
* @param p a PrintStream usually supplied by Logger
* @param indent indention string, usually suppiled by Logger
* @see org.jpos.util.Loggeable
*/
public void dump (PrintStream p, String indent) {
String inner = indent + " ";
p.print(indent + "");
p.println(inner + "" + ISOUtil.hexString(getPINBlock()) + " ");
p.println(inner + "" + getAccountNumber() + " ");
p.println(indent + " ");
}
/**
*
* @param pinBlock
*/
public void setPINBlock (byte[] pinBlock) {
this.pinBlock = pinBlock;
}
/**
*
* @return pinBlock
*/
public byte[] getPINBlock () {
return pinBlock;
}
/**
*
* @param pinBlockFormat
*/
public void setPINBlockFormat (byte pinBlockFormat) {
this.pinBlockFormat = pinBlockFormat;
}
/**
*
* @return PIN Block Format
*/
public byte getPINBlockFormat () {
return this.pinBlockFormat;
}
/**
* Sets the 12 right-most digits of the account number excluding the check digit
* @param extractedAccountNumber 12 right-most digits of the account number, excluding the check digit.
*/
public void setAccountNumber (String extractedAccountNumber) {
if(extractedAccountNumber.length() != 12)
throw new InvalidParameterException(
"Extracted account number length should be 12, got '"
+ISOUtil.protect(extractedAccountNumber) + "'"
);
this.accountNumber = extractedAccountNumber;
}
/**
* @return accountNumber (the 12 right-most digits of the account number excluding the check digit)
*/
public String getAccountNumber () {
return accountNumber;
}
/**
* This method extracts the 12 right-most digits of the account number,
* execluding the check digit.
* @param accountNumber (PAN) consists of the BIN (Bank Identification Number), accountNumber
* and a check digit.
* @return the 12 right-most digits of the account number, execluding the check digit.
* In case if account number length is lower that 12 proper count of 0 digts is added
* on the left side for align to 12
*/
public static String extractAccountNumberPart (String accountNumber) {
String accountNumberPart = null;
try {
accountNumberPart = ISOUtil.takeLastN(accountNumber, 13);
accountNumberPart = ISOUtil.takeFirstN(accountNumberPart, 12);
} catch(ISOException ex) {}
return accountNumberPart;
}
}