Buenas.

Sigo con mis cacharreos con el DNI. El tema de la autenticación lo tengo bastante avanzado y ahora me he metido tambien con el acceso a los datos públicos del DNI via APDU mediante javax.smartcardio que viene en Java 1.6. y siguiendo los pasos de este post.

El código java que tengo hecho hasta el momento es el siguiente:

import javax.smartcardio.*;

import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.util.*;

public class Lector {
	public void Test(){
		String hex = "00A40000025015";
		byte[] primer_msg = new BigInteger(hex, 16).toByteArray(); 
		hex = "00A40000026004";
		byte[] segundo_msg = new BigInteger(hex, 16).toByteArray();
		
		String SW1;
		String SW2;
	    // show the list of available terminals
	    TerminalFactory factory = TerminalFactory.getDefault();
	    List terminals;
		try {
			terminals = factory.terminals().list();

		    System.out.println("Terminals: " + terminals);
		    // get the first terminal
		    CardTerminal terminal = terminals.get(0);
		    // establish a connection with the card
		    Card tarjeta = terminal.connect("T=0");
		    System.out.println("card: " + tarjeta);
		    CardChannel channel = tarjeta.getBasicChannel();
		    ResponseAPDU r = channel.transmit(new CommandAPDU(primer_msg));
		    System.out.println("response mensaje 1: " + getHexString(r.getBytes()));
		    SW1=getHexString(r.getBytes()).substring(0, 2);
		    SW2=getHexString(r.getBytes()).substring(2);
	            r = channel.transmit(new CommandAPDU(segundo_msg));
	            System.out.println("response mensaje 2: " +    getHexString(r.getBytes()));
                    hex = "00C00000" + getHexString(r.getBytes()).substring(14,18);			    System.out.println(getHexString(r.getBytes()).substring(14,18));
			    System.out.println(hex);
				byte[] tercer_msg = new BigInteger(hex, 16).toByteArray();
				r = channel.transmit(new CommandAPDU(tercer_msg));
			    System.out.println("response mensaje 3: " + getHexString(r.getBytes()));
			    // disconnect
			    tarjeta.disconnect(false);
		    
		} catch (CardException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static String getHexString(byte[] b) throws Exception {
		  String result = "";
		  //System.out.println("BYTES DE RESPUESTA: " +b.length);
		  for (int i=0; i < b.length; i++) {
		    result +=
		          Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
		  }
		  return result;
		}

}

De momento este código me debería permitir llegar al paso 3 del otro post es decir "Envias 00C00000LE LE es el valor dado por SW2 en el segundo paso."

El problema es que en vez de dos bytes en los pasos 1 y 2 recibo largas cadenas de bytes. Esto tambíen se explica en el otro post y es debido a que hay una lectura semi automatica de los datos en cada paso.

¿Hay alguna forma de conseguir evitar esa automatización con el código java de tal forma que al recibir la respuesta de cada paso no haya lecturas automaticas de datos?

En caso de que no la haya, tambien lei en el otro post que con la respuesta del paso 2 puedo sacar el LE para el paso 3, en mi caso la respuesta del paso 2 es 6f0c850a01600405100080ffffff9000. He marcado en negrita lso 4 bytes que se marcan en el otro post de los cuales 6004 sería el ID del fichero y 0510 la longitud.

¿Que le tendría que pasar al siguiente comando 00C00000LE como LE, 51? Si le paso 0510 (qué es lo que hago en el código con getHexString(r.getBytes()).substring(14,18)) obtengo un error de lóngitud "java.lang.IllegalArgumentException: Invalid APDU: length=6, b1=5" al enviar el mensaje que quedaría 00C000000510.

Gracias como siempre por las posibles respuestas.