Comprobación de ATR mediante Suma de Verificación XOR [Código Java]

FE26DS8GJ7MQAYF.MEDIUMCada vez que conectamos un SmartCard y hacemos la conexión correspondiente, obtenemos la cadena de respuesta del Chip conocida como ATR, pero ¿como verificar si el ATR recibido es correcto? para ello la norma ISO estable que el último byte recibido corresponde a uno de verificación desde el byte T0 hasta el Tj, donde T0 es el segundo byte del atr en mención y el byte Tj corresponde al penúltimo, por lo que el último es un byte de comprobación. Para ello se debe de usar una suma de verificación XOR.

ISO7816_23

Por ejemplo y para hacerlo de manera sencilla el ATR siguiente se comprobarían de la siguiente manera:

3B DB 96 00 80 B1 FE 45 1F 83 00 31 C0 64 C3 08 01 00 0F 90 00 9B

3B sería el byte incial, el cual se omite
DB 96 00 80 B1 FE 45 1F 83 00 31 C0 64 C3 08 01 00 0F 90 00 Sería la serie de bytes a comprobar (T0 – Tj)
9B sería la suma de verificación de los bytes T0 – Tj
por lo cual si la suma de verifciación xor desde T0 hasta Tj es distinta de 9B, este ATR estaría incorrecto o alterado.

 

A continuación un código de java que facilita la comprobación debida.

/*
 * Version 1.0 Revision 1
 *
 * 18/08/2014
 *
 * Copyright 2014 bit502
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 */



/**
 *
 * @author Julio Chinchilla
 */
public class ATRVerify {

    /**
     * Función que recibe un ATR en formato String con separador de espacio
     * entre cada byte, la función formatea la cadena de caracteres quitándole
     * los espacios en blanco, posteriormente separa los bytes T0 hasta TJ en
     * el String t0tj y separa el byte de comprobación final TCK, luego utiliza
     * la función getXORCheckSumValue para obtener la suma verificativa y lo
     * compara con el byte TCK, si los bytes coinciden la respuesta será true
     * de lo contrario será false, y el ATR a verificar estará incorrecto
     * @param atr ATR con espacios entre bytes
     * @return
     */
    public static boolean checkATRStrWS (String atr) {
        boolean resp = false;
        String t0tj = atr.replaceAll("\\s","");
        String tck = atr.substring(atr.length()-2, atr.length());
        t0tj = t0tj.substring(2, t0tj.length()-2);
        if (getXORCheckSumValue(t0tj).equals(tck))
            resp = true;
        return resp;
    }

    /**
     * Función que recibe un ATR en formato String con separador de espacio
     * entre cada byte, posteriormente separa los bytes T0 hasta TJ en
     * el String t0tj y separa el byte de comprobación final TCK, luego utiliza
     * la función getXORCheckSumValue para obtener la suma verificativa y lo
     * compara con el byte TCK, si los bytes coinciden la respuesta será true
     * de lo contrario será false, y el ATR a verificar estará incorrecto
     * @param atr ATR sin espacios entre bytes
     * @return
     */
    public static boolean checkATRStr (String atr) {
        boolean resp = false;
        String t0tj = atr.substring(2, atr.length()-2);;
        String tck = atr.substring(atr.length()-2, atr.length());
        if (getXORCheckSumValue(t0tj).equals(tck))
            resp = true;
        return resp;
    }

    /**
     * Función que realiza una suma de verificación a una cadena String en
     * formato Hexadecimal con el operador XOR
     * @param bytes Cadena String en formato hexadecimal a analizar
     * @see <a href="http://es.wikipedia.org/wiki/Suma_de_verificaci%C3%B3n">WikiES: Suma de verificación</a>
     * @return String de comprobación mediante Suma de Verificación HEX
     */
    private static String getXORCheckSumValue (String bytes) {
        int cc = 0;
        for (int i = 0; i < bytes.length(); i=(i+2)) {
            if (i==0){
                cc = Integer.parseInt(bytes.substring(i, i+2), 16) & (0x00FF);
            } else {
                cc^=(Integer.parseInt(bytes.substring(i, i+2),16)&(0x00FF));
                cc=cc&(0x00FF);
            }
        }
        return Integer.toString(cc, 16).toUpperCase();
    }

}

Su forma de uso es la siguiente:

/**
 *
 * @author Julio
 */
public class ATRVerify {

    public static final String GT01 = "3B DB 96 00 80 B1 FE 45 1F 83 00 31 C0 64 C3 08 01 00 0F 90 00 9B";
    public static final String GT02 = "3BDB960080B1FE451F830031C064C7FC10000F90007A";
    public static final String ATR1 = "3B DB 18 00 80 1F 03 00 31 C0 64 77 E3 03 00 82 90 00 4F";

    public static void main(String[] args) {
        System.out.println(checkATRStrWS(GT02));
        System.out.println(checkATRStr(GT02));
        System.out.println(checkATRStrWS(ATR1));
    }

}
Anuncios

3 pensamientos en “Comprobación de ATR mediante Suma de Verificación XOR [Código Java]

  1. Ludwing Rodas

    Buena tarde Julio, he estado viendo su blog y me parece muy interesante, estamos en un proyecto para poder leer el DPI ya que en la empresa le damos empleo a mas de 5000 personas y teclear la información es tedioso, usted sabra la forma de poder leer esta información? me interesa mas que todo la información general de la persona, mi correo es rrodasm@gmail.com.

    Responder
  2. otto farfan

    Que tal Julio, le comento que estoy en el desarrollo de  una aplicación de que lee los DPI, para la institucion en la que laboro, ya tengo construida la solución, pero los APDU para accesar a la zona publica del DPI los desconozco, ya que los que e probado me devuelven únicamente “67 00(Wrong length)”. Sabra alguna fuente que me pueda servir para saber como esta constituida esta área publica o  tal vez pudiera darme algunos tips. nos podríamos poner en contacto?, le dejo por acá mi mail,

    orfarfan06@gmail.com. slds.

     

    Responder
  3. Pingback: Accediendo al nuevo chip Smart Card del DPI (Fase I) | bit502

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s