javax.smartcardio: como enviar comandos nativos para a placa Desfire?

Estou criando um aplicativo java se comunicando com uma placa Mifare DESFire através de um leitor sem contato PC / SC e da API javax.smartcardio. Consigo enviar regularmente APDUs ISO 7816 (CLA, INS, P1-P2, Lc, Dados de comando, Le).

Eu li sobreBlog da Ridrix que as placas DESFire (pelo menos a versão EV1 que estou usando) suportam APDUs eComandos nativos onde a maioria dos comandos tem apenas 1 byte.

Por exemplo, o "Obter versão"comando:

Command: 60
Response: af 04 01 01 00 02 18 05

Eu testei esse comando com oPC / SC Diag programa deSpringCard (disponivel aqui) e recebo uma resposta correta.

Mas eu não posso enviar este comando com javax.smartcardio: esta API parece ter sido criada parareal APDUs e, portanto, não permite comandos longos de 1 byte.

Aqui está o que eu fiz:

public static void main(String[] args){
    TerminalFactory factory = TerminalFactory.getDefault();
    CardTerminals terminalList = factory.terminals();

    try {
        CardTerminal ct = terminalList.list().get(0);       
        ct.waitForCardPresent(0);
        Card card = ct.connect("*");
        CardChannel channel = card.getBasicChannel();

        byte[] command = { 0x60 };

        channel.transmit(new CommandAPDU(command));
    } catch (CardException e) {
        e.printStackTrace();
    }
}

Isso me dá o seguinte erro:

Exception in thread "main" java.lang.IllegalArgumentException: apdu must be at least 4 bytes long
    at javax.smartcardio.CommandAPDU.parse(Unknown Source)
    at javax.smartcardio.CommandAPDU.<init>(Unknown Source)

Eu tentei a única maneira (AFAIK) de enviar um comando:

        ByteBuffer command = ByteBuffer.allocate(1);
        command.put((byte) 0x60);

        ByteBuffer response = ByteBuffer.allocate(512);

        channel.transmit(command, response);

e obter um erro semelhante:

Exception in thread "main" java.lang.IllegalArgumentException: Command APDU must be at least 4 bytes long
    at sun.security.smartcardio.ChannelImpl.checkManageChannel(Unknown Source)
    at sun.security.smartcardio.ChannelImpl.doTransmit(Unknown Source)
    at sun.security.smartcardio.ChannelImpl.transmit(Unknown Source)

Você sabe de alguma maneira de enviar este tipo de comando usando javax.smartcardio ou outra coisa?

Eu sei que é possívelembrulho esses comandos, mas eu preferiria usar os comandos nativos (mais simples).

Obrigado.

questionAnswers(3)

yourAnswerToTheQuestion