[Transferir] PIN estándar ANSI X9.8 xo PAN para obtener PIN BlOCK

Vi algunas introducciones antes, diciendo que ANSI tiene 16 bytes, lo cual es realmente una tontería y es engañoso. El algoritmo ANSI real es en realidad de 8 bytes. El formato específico es el siguiente:

 

(1) Formato ANSI X9.8 ( sin información de cuenta maestra )

PIN (Número de identificación personal) tiene una longitud total de 8 bytes, divididos en dos partes; (similar al formato de paquete de datos)

1: Byte1  registra la longitud del PIN

2: Byte2-Byte8 6-12 dígitos (caracteres) PIN (Cada carácter ocupa 4 BIT, si es menos de 8 dígitos, complemento a la derecha F)

Por ejemplo: el PIN de texto sin formato es 123456,

Entonces PIN BLOCK es 0x06 0x12 0x34 0x56 0xFF 0xFF 0xFF 0xFF

0x06 registra que la longitud del PIN es 6 y los siguientes 16 bits se rellenan con F y luego se convierten en código BCD (el código BCD es un número binario de 8 bits como una unidad, es decir, el tamaño de un Byte es también un número hexadecimal HEX Occupancy length).

 

( 2) Formato ANSI X9.8 ( con información de la cuenta principal )
Formato PIN BLOCK: igual al PIN bit a bit
Formato del PIN de la cuenta principal XOR : (similar al formato en
1 ) Byte 1 Longitud del PIN
Byte 2 - Byte 3/4/5 / 6/7 4--12 PIN (cada PIN ocupa 4 BIT)
Byte 4/5/6/7/8 - Byte 8 RELLENO “F” (Cada “F” ocupa 4 BIT)

PAN (Número de cuenta principal de la cuenta principal) también contiene 8 bytes, y el formato es el siguiente:
Byte 1 - Byte 2 0x00 0x00
Byte 3 - Byte 8 12 caracteres de la cuenta principal (el último dígito es el dígito de control) Se
selecciona el número de cuenta principal de 12 caracteres:
tome el principal El derecho 12 dígitos del número de cuenta (sin incluir el dígito de control más a la derecha), si tiene menos de 12 dígitos, el complemento a la izquierda es "0X00 ".


ejemplo:

PIN de texto sin formato: 123456,
cuenta principal PAN: 123456789012345678 La
cuenta principal interceptada es: 678901234567 (Los primeros 12 caracteres del último dígito de control 8 son la cuenta principal interceptada)

El número de cuenta principal utilizado para el cifrado de PIN es: 0x00 0x00 0x67 0x89 0x01 0x23 0x45 0x67
luego BLOQUEO DE PIN (PIN exclusivo a nivel de bits O PAN de la cuenta principal)

Es decir: 0x06 0x12 0x34 0x56 0xFF 0xFF 0xFF 0xFF
XOR arriba: 0x00 0x00 0x67 0x89 0x01 0x23 0x45 0x67 El
resultado es:  
0x06 0x12 0x53 0xDF 0xFE 0xDC 0xBA 0x98

 

Util.java

package CodeApe;

public class Util {
 public Util() {

 }

 
 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;
 }

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

}

ANSIFormat.java

 

package CodeApe;

import java.io.ObjectInputStream.GetField;

import javax.annotation.processing.Processor;

import CodeApe.Util;

public class ANSIFormat {

 private String pin;
 private String accno;
 public ANSIFormat(String pin , String accno){
  this.pin = pin;
  this.accno = accno;
 }
 
 public byte[] process(String pin, String accno) {
     byte arrPin[] = getHPin(pin);
     byte arrAccno[] = getHAccno(accno);
     byte arrRet[] = new byte[8];
     //PIN BLOCK 格式等于 PIN 按位异或 主帐号;
     for (int i = 0; i < 8; i++) {
       arrRet[i] = (byte) (arrPin[i] ^ arrAccno[i]);
     }
    
     Util.printHexString("PinBlock:", arrRet);
     return arrRet;
 }

 
 private byte[] getHPin(String pin) {
     byte arrPin[] = pin.getBytes();
     byte encode[] = new byte[8];
     encode[0] = (byte) 0x06;
     encode[1] = (byte) Util.uniteBytes(arrPin[0], arrPin[1]);
     encode[2] = (byte) Util.uniteBytes(arrPin[2], arrPin[3]);
     encode[3] = (byte) Util.uniteBytes(arrPin[4], arrPin[5]);
     encode[4] = (byte) 0xFF;
     encode[5] = (byte) 0xFF;
     encode[6] = (byte) 0xFF;
     encode[7] = (byte) 0xFF;
     Util.printHexString("encoded pin:", encode);
     return encode;
 }

 
 private byte[] getHAccno(String accno) {
     //取出主帐号;
     int len = accno.length();
     byte arrTemp[] = accno.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) Util.uniteBytes(arrAccno[0], arrAccno[1]);
     encode[3] = (byte) Util.uniteBytes(arrAccno[2], arrAccno[3]);
     encode[4] = (byte) Util.uniteBytes(arrAccno[4], arrAccno[5]);
     encode[5] = (byte) Util.uniteBytes(arrAccno[6], arrAccno[7]);
     encode[6] = (byte) Util.uniteBytes(arrAccno[8], arrAccno[9]);
     encode[7] = (byte) Util.uniteBytes(arrAccno[10], arrAccno[11]);
     Util.printHexString("encoded accno:", encode);
     return encode;
 }

 
}

test.java(测试类)

 

package CodeApe;

public class test {

 private static ANSIFormat pass;
 
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  String pin = "123456";
  String accno = "123456789012345678";
  System.out.println("encoded pin:"+pin);
  System.out.println("encoded accno:"+accno);
  pass = new ANSIFormat(pin, accno);
  byte[] b = pass.process(pin, accno);
  
 }

}

Código fuente del algoritmo: (incluida una clase de herramienta Util y una clase de conversión ANSIFormat.java)
representaciones

 

http://wenku.

Supongo que te gusta

Origin blog.csdn.net/zhengjian1996/article/details/112933725
Recomendado
Clasificación